home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / misc / emu / QDOS2.lha / QLsource / ROMsrc / FLP / FLP1_asm < prev    next >
Text File  |  1995-01-02  |  69KB  |  2,944 lines

  1. */beginfile FLP1_asm
  2. ; --------------------------------------------------------------
  3. ; FLP1_asm - floppy disk device driver for QDOS
  4. ;      - last modified 02/01/95
  5.  
  6. ; Floppy disk driver for CST    (c) 1984  Tony Tebby      QJUMP
  7. ; Modified for CST maintenance  (c) 1986  David Oliver  CST.
  8. ; Modified for Amiga floppies   (c) 1989  Rainer Kowallik
  9. ;                      Public Domain
  10. ; --------------------------------------------------------------
  11.  
  12. ; keys for floppy disc system
  13.  
  14. fs_next    equ    $18
  15. fs_acces equ    $1c
  16. fs_drive equ    $1d
  17. fs_filnr equ    $1e
  18. fs_nblok equ    $20
  19. fs_nbyte equ    $22
  20. fs_eblok equ    $24
  21. fs_ebyte equ    $26
  22. fs_cblok equ    $28
  23. fs_updt    equ    $2c
  24.  
  25. fs_fname equ    $32
  26. fs_spare equ    $58
  27. fs_end    equ    $a0
  28.  
  29. fs.nmlen equ    $24
  30. fs.hdlen equ    $40
  31.  
  32. ; floppy disk physical layer
  33.  
  34. fdd_xilk equ    $00        ; link for external
  35.                 ; interrupt 2
  36. fdd_pllk equ    $08        ; link for polling interrupt
  37. fdd_shlk equ    $10        ; link for schedular
  38. fdd_ddlk equ    $18        ; link for directory devices
  39. fdd_iolk equ    $1c        ; link to io routine
  40. ;
  41. fdd_name equ    $3e        ; 4*b name (ends with 0)
  42. fdd_side equ    $42        ; b side number
  43. fdd_driv equ    $43        ; b drive number
  44. fdd_sadd equ    $44        ; b side number to add to
  45.                 ; read/write command
  46. fdd_pend equ    $45        ; b flag for pending ops (<0
  47.                 ; start drive, >0 do not
  48.                 ; start)
  49. fdd_fint equ    $46        ; b set if forced interrupt
  50. fdd_nset equ    $47        ; b set if name set
  51. fdd_step equ    $48        ; 4*b step rates per drive
  52.                 ; (-1 is not set)
  53. fdd_slen equ    $4c        ; 4*b sector length per
  54.                 ; drive (0=128)
  55.  
  56. fdd_wprt equ    $50        ; 4*b write protect per
  57.                 ; drive (also 40/80 if +ve)
  58. fdd_sden equ    $54        ; 4*b single density flag
  59.                 ; per drive
  60. fdd_rbeg equ    $58        ; w number of bytes to skip
  61.                 ; at beginning of record
  62. fdd_rend equ    $5a        ; w number of bytes to skip
  63.                 ; at end of record
  64. fdd_time equ    $5c        ; b time_out for watchdog
  65.                 ; (set by any action)
  66. fdd_rnup equ    $5d        ; b run-up counter
  67. fdd_rndn equ    $5e        ; b run_down counter
  68. fdd_wait equ    $5f        ; b timer for pending ops.
  69. fdd_scty equ    $60        ; b security level
  70. fdd_ntrk equ    $61        ; b number of tracks
  71. fdd_stim equ    $62        ; b start up time
  72. fdd_sord equ    $63        ; b step rate order 0 =
  73.                 ; 6,12,20,30, 2=6,12,2,3
  74. fdd_chck equ    $64        ; 4*b -ve if drive has been
  75.                 ; checked since
  76.                 ; stopped/deselected
  77. fdd_pact equ    $68        ; b flag, if polled task is
  78.                 ; already active
  79. fdd_end    equ    $6A
  80.  
  81. fs_drivr equ    $10
  82. fs_drivn equ    $14
  83.  
  84. fs_mname equ    $16        ; medium name
  85. fs_files equ    $22        ; number of files open
  86.  
  87. fd_estat equ    $23        ; error status 0=ok, -1=bad,
  88.                 ; 1=ignore
  89. fd_fail    equ    $24        ; failure count
  90. fd_mupdt equ    $25        ; map updated
  91. fd_sflag equ    $26        ; sector read/write flag
  92. fd_mwrit equ    $27        ; map to be written
  93. fd_pend    equ    $28        ; pending operation list
  94. fd.npend equ    $0A        ; 10 ops max
  95. fd_mhead equ    $50        ; medium header
  96. fd_fmtid equ    $50        ; format ID
  97. fd.fmtid equ    'QL5A'
  98. fd_mdnam equ    $54        ; ... medium name
  99. fd_mdupd equ    $60        ; ... count of updates
  100. fd_mfree equ    $64        ; ... free sectors in map
  101. fd_mgood equ    $66        ; ... good sectors in map
  102. fd_mtotl equ    $68        ; ... total sectors in map
  103. fd_mstrk equ    $6a        ; ... sectors per track
  104. fd_mscyl equ    $6c        ; ... sectors per cylinders
  105. fd_mtrak equ    $6e        ; ... number of tracks
  106.                 ; (cylinders)
  107. fd_mallc equ    $70        ; ... sectors per group
  108. fd_meodr equ    $72        ; ... current end of
  109.                 ; directory (block/byte
  110.                 ; format)
  111. fd_msoff equ    $76        ; ... sector offset
  112. fd_mlgph equ    $78        ; ... logical to physical
  113.                 ; sector translate
  114. fd_mphlg equ    $8a        ; ... physical to logical
  115.                 ; sector translate
  116.  
  117. fd_map    equ    $b0        ; sector map in 3 byte
  118.                 ; entries
  119. fd_end    equ    fd_mhead+3*512
  120.  
  121. fd_delen equ    $00
  122. fd_deacs equ    $04
  123. fd_detyp equ    $05
  124. fd_deinf equ    $06
  125. fd_denam equ    $0e
  126. fd_deupd equ    $34
  127. fd_deend equ    $40
  128. fd.desft equ    $6        ; shift to convert entry
  129.                 ; number to position
  130.  
  131. fds..bsy equ    0        ; status busy bit
  132. fds..drq equ    1        ; status data request bit
  133. fds..ind equ    1        ; status index pin bit
  134. fds..lst equ    2        ; status lost data bit
  135. fds..tr0 equ    2        ; status track 0 bit
  136. fds..crc equ    3        ; status crc error bit
  137. fds..rnf equ    4        ; status record not found
  138.                 ; bit
  139. fds..spn equ    5        ; status spun up bit
  140. fds..wpr equ    6        ; status write protect bit
  141. fds..mot equ    7        ; status motor on bit (1770)
  142. fds..nrd equ    7        ; status not ready bit
  143.                 ; (2793)
  144.  
  145. fds.bsy    equ    %00000001    ; busy
  146. fds.drq    equ    %00000010    ; data request
  147. fds.ind    equ    %00000010    ; index pin
  148. fds.rwok equ    %01011100    ; read/write ok mask
  149. fds.raok equ    %00011000    ; read address ok mask
  150.  
  151. ; --------------------------------------------------------------
  152. ; Keys for CST QDisc controller (specific).
  153.  
  154. fd_statr equ    0        ; ... assumed 0!!!
  155. fd_comdr equ    0        ; ... assumed 0!!!
  156. fd_trakr equ    2
  157. fd_sectr equ    1
  158. fd_datar equ    3
  159. fd_ctrlr equ    8
  160.  
  161. fdf.rate equ    %00000000    ; 6 ms step rate
  162. fdf.slow equ    %00000011    ; 30 ms step rate
  163. fdf.prec equ    %00000010    ; precompensate no tracks
  164. fdf.veri equ    %00000100
  165. fdf.setl equ    %00000000    ; no settling time
  166. fdf.strt equ    %00001000    ; no 6 cycle start up
  167.  
  168. fdc.rest equ    %00000000+fdf.strt+fdf.rate
  169. fdc.seek equ    %00010000+fdf.strt+fdf.rate
  170. fdc.stin equ    %01010000+fdf.strt+fdf.rate
  171. fdc.read equ    $ffffff00+%10000000+fdf.strt+fdf.setl
  172. fdc.writ equ    $ffffff00+%10100000+fdf.strt+fdf.setl+fdf.prec
  173. fdc.radd equ    $ffffff00+%11000000+fdf.strt+fdf.setl
  174. fdc.fint equ    $ffffff00+%11010000
  175. fdc.rtrk equ    $ffffff00+%11100000+fdf.strt+fdf.setl
  176. fdc.wtrk equ    $ffffff00+%11110000+fdf.strt+fdf.setl+fdf.prec
  177.  
  178. fdd.rnup equ    30        ; write run up time
  179. fdd.wait equ    50        ; wait for write time
  180. fdd.rndn equ    20        ; run down after motor off
  181.  
  182. fd.ndriv equ    2        ; max number of drives
  183. fd.singl equ    'S'
  184.  
  185. fdc.add    equ    %00010000    ; constant to write to
  186.                 ; control register
  187. fdc.init equ    %00010010    ; initial control reg value
  188.                 ; (drive one selected)
  189. fdc.desl equ    %00000000    ; deselected control reg
  190.                 ; value
  191. fdc.oops equ    %00000000    ; error control reg value no
  192.                 ; drive, no motor
  193. fdc.sing equ    %00001000    ; constant to add for single
  194.                 ; density
  195. fdd.name equ    'FLP0'
  196.  
  197. ; --------------------------------------------------------------
  198. rom_base
  199.     dc.l    $4afb0001
  200.     dc.w    proc_tab-rom_base
  201.     dc.w    rom_init-rom_base
  202.     dc.b    0,37,'FLP device driver v1.17:03  1984-94',$a,0
  203.     dc.w    0
  204. ; --------------------------------------------------------------
  205.  
  206. fds_fo_mess dc.b    0,18,' files still open',$a
  207.     ds.w    0
  208.  
  209. fds_rw_mess dc.b    0,19,' read/write failed',$a
  210.     ds.w    0
  211. ; --------------------------------------------------------------
  212. rom_init
  213.  
  214.     bra.l    fd_init
  215.  
  216. ; --------------------------------------------------------------
  217. proc_tab
  218.     ifd    extras
  219.  
  220.     dc.w    13        ; 7 procedures
  221.  
  222.     dc.w    flp_sec-*    ; FLP_SEC security_level
  223.     dc.b    7,'FLP_SEC'    ; (0 to 2)
  224.     dc.w    flp_start-*    ; FLP_START start_up_time
  225.     dc.b    9,'FLP_START'    ; (in 20 ms)
  226.     dc.w    flp_track-*    ; FLP_TRACK nr_of_tracks
  227.     dc.b    9,'FLP_TRACK'
  228.  
  229.     endc
  230.  
  231.     ifnd    extras
  232.  
  233.     dc.w    8        ; 4 procedures
  234.  
  235.     endc
  236.  
  237.     dc.w    flp_use-*
  238.     dc.b    7,'FLP_USE'
  239.     dc.w    prog_use-*
  240.     dc.b    8,'PROG_USE',0
  241.     dc.w    data_use-*
  242.     dc.b    8,'DATA_USE',0
  243.     dc.w    dest_use-*
  244.     dc.b    8,'DEST_USE',0
  245.     dc.w    spl_use-*
  246.     dc.b    7,'SPL_USE'
  247.     dc.w    0        ; end of procedures
  248.  
  249.     dc.w    3        ; no functions
  250.     dc.w    prog_d$-*
  251.     dc.b    6,'PROGD$',0
  252.     dc.w    data_d$-*
  253.     dc.b    6,'DATAD$',0
  254.     dc.w    dest_d$-*
  255.     dc.b    6,'DESTD$',0
  256.     dc.w    0        ; end of functions
  257.  
  258.  
  259. ; --------------------------------------------------------------
  260. fd_init
  261.     movem.l    a0/a3,-(sp)
  262.     moveq    #fdd_end,d1
  263.     moveq    #MT.ALCHP,d0
  264.     moveq    #0,d2
  265.     trap    #1
  266.  
  267.     lea    fd_poll(pc),a2
  268.     move.l    a2,fdd_pllk+4(a0) ; !
  269.  
  270.     lea    fdd_iolk(a0),a3
  271.     lea    fd_io(pc),a2
  272.     move.l    a2,(a3)+     ; input/output... at $1c
  273.     lea    fd_opn(pc),a2
  274.     move.l    a2,(a3)+     ; open... at $20
  275.     lea    fd_clos(pc),a2
  276.     move.l    a2,(a3)+     ; close... at $24
  277.     lea    fd_slave(pc),a2    ; slave
  278.     move.l    a2,(a3)+
  279.     addq.l    #8,a3        ; two spare
  280.     lea    fd_format(pc),a2    ; format
  281.     move.l    a2,(a3)+
  282.     move.l    #fd_end,(a3)+    ; length
  283.     move.w    #3,(a3)+
  284.     move.l    #'FLP0',(a3)+
  285.     addq.l    #6,a3        ; side/drive/side
  286.                 ; add/empty/fint/name set
  287.     subq.l    #1,(a3)+     ; all step rates unset
  288.     move.l    #$02020202,(a3)    ; 512 byte sectors
  289.  
  290.     addq.b    #1,fdd_scty(a0)    ; set security level
  291.     move.b    #fdd.rnup,fdd_stim(a0) ; and default motor
  292.                      ; start time
  293.     move.l    a0,a3
  294.  
  295.     lea    fdd_pllk(a3),a0    ; link into
  296.     moveq    #MT.LPOLL,d0    ; polling list !
  297.     trap    #1
  298.  
  299.     lea    fdd_ddlk(a3),a0    ; link into
  300.     moveq    #MT.LDD,d0    ; dd driver list
  301.     trap    #1
  302.  
  303. fdini_arel
  304.     st    fdd_driv(a3)    ; set silly drive number
  305.     clr.l    fdd_chck(a3)    ; mark drives not selected
  306.     bsr.l    fd_arel
  307.  
  308.     moveq    #MT.ALCHP,d0    ; make space for defaults
  309.     moveq    #3*36,d1     ; ** 1.17 **
  310.     moveq    #0,d2
  311.     trap    #1
  312.     move.l    a0,a4        ; save pointer
  313.     moveq    #MT.INF,d0    ; find the system variables
  314.     trap    #1
  315.     lea    SV_PROGD(a0),a0    ; and set the pointers to
  316.                 ; the defaults
  317.     move.l    #$00050000+'FL',d1
  318.     move.l    #'P1_ ',d2
  319.     move.l    a4,(a0)+     ; program default FLP1_
  320.     move.l    d1,(a4)+
  321.     move.l    d2,(a4)
  322.     add.w    #32,a4
  323.     move.l    a4,(A0)+     ; data default FLP1_
  324.     move.l    d1,(a4)+
  325.     move.l    d2,(a4)
  326. ;     add.w     #1,(a4)      ; Data default now FLP2_
  327.     add.w    #32,a4
  328.     move.l    a4,(a0)+     ; spool default PAR
  329.     move.l    #$00030000+'PA',(a4)+
  330.     move.b    #'R',(a4)+
  331.  
  332.     BSR    user_ini
  333.  
  334.     movem.l    (sp)+,a0/a3
  335.     rts
  336. ; --------------------------------------------------------------
  337. ; internal adaption to user routines
  338. ; --------------------------------------------------------------
  339. fd_selct:
  340.     move.b    d1,fdd_driv(a3)
  341.     bra.l    fd_select
  342. fd_side1:
  343.     move.b    d1,fdd_side(a3)
  344.     bra.l    fd_side
  345. fd_crdy:
  346.     bsr    fd_ckrdy
  347.     tst.b    d0
  348.     beq.s    crdy_rts
  349.     move.w    d0,-(a7)
  350.     bsr    fd_restore
  351.     move.w    (a7)+,d0
  352.     tst.b    d0
  353. crdy_rts rts
  354. ; --------------------------------------------------------------
  355. ; Floppy disc utilities, read, write, seek     1984 Tony Tebby
  356. ; 1770/1793 version
  357.  
  358. ;       d1 c s  track or sector to seek
  359. ;      length of read/write -1
  360. ;       a1 cr   pointer to data buffer
  361. ;       a2  r   ptr to data reg (read/write/write track only)
  362. ;       a3 c p  pointer to physical definition
  363. ;       a4 c p  pointer to status/command register
  364. ;       !!!!! a4 and a2 are not used in the AMIGA routines !!!!
  365.  
  366. ; seek using 40/80 flag
  367.  
  368. fd_seek40
  369.     moveq    #0,d0        ; get drive number
  370.     move.b    fdd_driv(a3),d0
  371.     tst.b    fdd_wprt-1(a3,d0.w) ; is it 40 in 80?
  372.     ble    fd_seek        ; ... no
  373.     move.b    d1,-(sp)     ; save real track
  374.     add.b    d1,d1        ; seek twice as far
  375. ; move.b fd_trakr(a4),d0
  376. ; add.b    d0,fd_trakr(a4)
  377.     bsr    fd_seek
  378.     move.b    (sp)+,d1     ; \\fd_trakr(a4)       set
  379.                 ; real track
  380.     rts
  381.  
  382. ; seek to track
  383.  
  384. fd_seekr
  385.     BRA    fd_seek        ; otherwise use fd_seek
  386.                 ; anyway
  387. fd_poll
  388.     tst.b    fdd_wait(a3)    ; are we waiting for do all
  389.                 ; pending
  390.     blt.s    fdp_rts        ; ... waitng for ever
  391.     beq.s    fdp_pend     ; ... no
  392.     subq.b    #1,fdd_wait(a3)    ; ... yes, decrement wait
  393. fdp_rts
  394.     rts
  395. fdp_pend
  396.     tst.b    fdd_pend(a3)    ; are there any pending
  397.                 ; operations?
  398.     beq.s    fdp_rts        ; ... no
  399.     bsr.l    fd_do_all    ; do operations
  400.     bsr    FLUSHALL
  401.     rts
  402.  
  403. ; --------------------------------------------------------------
  404. ; Allocation routines for floppy disk IO
  405. ;  1984 Tony Tebby  QJUMP
  406.  
  407. ; routine to find the slave block for a sector
  408.  
  409. fdb_find
  410.     move.l    fs_cblok(a0),a4    ; get pointer to current
  411.                 ; block
  412.     move.l    a4,d0        ; is it set?
  413.     bne.s    fdb_fstrt
  414.     move.l    SV_BTBAS(a6),a4    ; start at base of tables
  415. fdb_fstrt
  416.     move.l    a4,a5        ; ... and keep a copy
  417.  
  418. fdb_check
  419.     moveq    #BT.INUSE,d0    ; set mask of in use bits
  420.     and.b    BT_STAT(a4),d0    ; check if this block is in
  421.                 ; use
  422.     beq.s    fdb_next     ; ... no
  423.     moveq    #$fffffff1,d0    ; set mask of drive id
  424.     and.b    BT_STAT(a4),d0    ; get drive id
  425.     cmp.b    d0,d6        ; is it the right drive
  426.     bne.s    fdb_next     ; ... no
  427.     moveq    #0,d0        ; preset error flag
  428.     cmp.l    BT_FILNR(a4),d5    ; is it the right file/block
  429.     beq.s    fdb_rts        ; ... yes
  430.  
  431. fdb_next
  432.     addq.l    #BT_END,a4    ; move to next entry in
  433.                 ; slave block tables
  434.     cmp.l    SV_BTTOP(a6),a4    ; ... is it off top
  435.     blt.s    fdb_last     ; ... no
  436.     move.l    SV_BTBAS(a6),a4    ; ... yes - start again at
  437.                 ; bottom
  438. fdb_last
  439.     cmp.l    a4,a5        ; have we been right the way
  440.                 ; round
  441.     bne.s    fdb_check    ; ... no - look at this next
  442.                 ; entry
  443. ; sector is not in slave blocks
  444.  
  445.     bsr.s    fdas_get     ; ... find the sector
  446.     bne.s    fdb_rts
  447.     bsr.s    fdb_new        ; ... allocate a new block
  448.     bne.s    fdb_rts
  449.     move.w    d2,BT_SECTR(a4)    ; ... set the sector number
  450.  
  451.     tst.w    d3        ; is operation send
  452.     bge.s    fdb_read     ; ... no
  453.     tst.w    d4        ; is this a first byte in a
  454.                 ; block?
  455.     bne.s    fdb_read     ; ... no
  456.     move.l    d7,d0        ; is end
  457.     sub.l    a1,d0        ; ... less start
  458.     sub.l    #$200,d0     ; >= one sector?
  459.     blt.s    fdb_read     ; ... no
  460.     bset    #BT..ACCS,BT_STAT(a4) ; ... yes, all will be
  461.                     ; overwritten
  462.     bra.s    fdb_ok
  463.  
  464. fdb_read
  465.     or.b    #BT.RREQ,BT_STAT(a4) ; tell fd to read it
  466.     bsr.l    fds_read     ; read it - now!
  467.     beq.s    fdb_ok        ; ... done
  468.  
  469. fdb_ncs
  470.     moveq    #ERR.NC,d0    ; not complete
  471. fdb_rts
  472.     rts
  473.  
  474. ; find a new block
  475.  
  476. fdb_new
  477.     move.l    SV_BTPNT(a6),a4    ; get current slave block
  478.                 ; pointer
  479.     move.l    a4,a5        ; ... save it
  480. fdb_nnext
  481.     addq.l    #8,a4        ; move to next
  482.     cmp.l    SV_BTTOP(a6),a4    ; off end yet?
  483.     blt.s    fdb_nchk     ; ... no
  484.     move.l    SV_BTBAS(a6),a4    ; ... yes, reset to base
  485. fdb_nchk
  486.     moveq    #%00001111,d1    ; mask out drive bits
  487.     and.b    BT_STAT(a4),d1
  488.     subq.b    #BT.EMPTY,d1    ; and check for empty
  489.     beq.s    fdb_nset     ; ... yes
  490.     subq.b    #BT.TRUE-BT.EMPTY,d1 ; ... not empty, check
  491.                    ; for true copy
  492.     beq.s    fdb_nset     ; ... yes true copy, reuse
  493.                 ; it
  494.     cmp.l    a5,a4        ; have we gone through all
  495.                 ; blocks
  496.     bne.s    fdb_nnext    ; ... no
  497.     bsr.l    fd_slave     ; $$$$$$$$$$$$$ temporary
  498.     bra.s    fdb_ncs        ; ... yes
  499.  
  500. fdb_nset
  501.     move.l    a4,fs_cblok(a0)    ; set current block
  502.     move.l    a4,SV_BTPNT(a6)    ; set block pointer
  503.     move.b    d6,BT_STAT(a4)    ; set empty
  504.     move.l    d5,BT_FILNR(a4)    ; ... set the file/block
  505. fdb_ok
  506.     moveq    #0,d0        ; no errors
  507.     rts
  508.  
  509. ; routine to find a sector group in the map
  510.  
  511. fdas_get
  512.     move.l    a4,-(sp)
  513.     lea    fd_map+2(a2),a5    ; get start of map+2
  514.     lea    fd_end(a2),a4    ; and end of map
  515.     bsr.s    fdas_comp
  516.     move.l    d0,d2        ; set sector number MOD
  517.                 ; alloc in top end
  518.     clr.w    d2
  519. fdasg_loop
  520.     cmp.b    (a5),d1        ; group matches?
  521.     bne.s    fdasg_lend
  522.     ror.l    #8,d1
  523.     cmp.b    -1(a5),d1    ; and next bit of file/group
  524.                 ; ?
  525.     bne.s    fdasg_l1
  526.     ror.l    #8,d1
  527.     cmp.b    -2(a5),d1    ; and last bit?
  528.     beq.s    fdasg_done
  529.     rol.l    #8,d1        ; restore comparison
  530.                 ; register
  531. fdasg_l1
  532.     rol.l    #8,d1
  533. fdasg_lend
  534.     addq.w    #1,d2        ; next group
  535.     addq.l    #3,a5
  536.     cmp.l    a4,a5        ; off end yet?
  537.     blt.s    fdasg_loop    ; ... no
  538.     moveq    #ERR.FE,d0    ; oops, not found
  539. fdasg_done
  540.     subq.l    #2,a5        ; set a5 to point to start
  541.     move.l    (sp)+,a4
  542.     rts
  543.  
  544. ; routine to calculate compressed form of file/group
  545.  
  546. fdas_comp
  547.     move.l    d5,d1        ; get file / block in d1
  548.     moveq    #0,d0        ; and convert to file /
  549.                 ; group
  550.     move.w    d1,d0
  551.     divu    fd_mallc(a2),d0
  552.     move.w    d0,d1
  553.     lsl.w    #4,d1        ; and stick them together
  554.     lsr.l    #4,d1
  555.     rts
  556.  
  557. ; routine to allocate a new sector
  558.  
  559. fdas_new
  560.     tst.w    d5        ; is this first sector?
  561.     beq.s    fdas_first    ; ... yes
  562.     subq.w    #1,d5        ; ... no, first find
  563.                 ; previous sector
  564.     bsr.s    fdas_get
  565.     bne.s    fdas_rts
  566.     addq.w    #1,d5        ; now set this sector
  567.     bsr.s    fdas_comp    ; compressed form in d1
  568.     swap    d0
  569.     tst.w    d0        ; block MOD alloc is zero?
  570.     bne.s    fdas_ok        ; ... no, then we've got new
  571.                 ; sector in old group
  572.     bsr.s    fdas_look    ; look for empty hole
  573.     beq.s    fdas_set     ; ... found
  574.     bra.s    fdas_retry    ; try again from start of
  575.                 ; disk
  576. fdas_first
  577.     bsr.s    fdas_comp    ; set compressed form in d1
  578.     moveq    #0,d2
  579.     move.w    fd_mscyl(a2),d2    ; ... no, keep clear of
  580.                 ; track 0
  581.     divu    fd_mallc(a2),d2
  582.     bsr.s    fdas_try     ; try once
  583.     beq.s    fdas_rts     ; ... ok
  584.  
  585. fdas_retry
  586.     moveq    #0,d2        ; try from start
  587. fdas_try
  588.     lea    fd_map(a2),a5    ; base of map
  589.     add.w    d2,a5        ; + sector offset
  590.     add.w    d2,a5
  591.     add.w    d2,a5
  592.     bsr.s    fdas_look    ; looking for an empty
  593.                 ; sector
  594.     bne.s    fdas_rts
  595. fdas_set
  596.     swap    d1
  597.     move.b    d1,(a5)+     ; set file/block in sector
  598.                 ; table
  599.     rol.l    #8,d1
  600.     move.b    d1,(a5)+
  601.     rol.l    #8,d1
  602.     move.b    d1,(a5)+
  603.  
  604.     move.w    fd_mallc(a2),d0
  605.     sub.w    d0,fd_mfree(a2)    ; one fewer free allocation
  606.                 ; blocks
  607.  
  608.     st    fd_mupdt(a2)    ; map updated
  609. fdas_ok
  610.     moveq    #0,d0
  611. fdas_rts
  612.     rts
  613.  
  614. ; look for an empty sector
  615.  
  616. fdas_look
  617.     move.l    a4,-(sp)     ; save a4
  618.     lea    fd_end(a2),a4    ; and set end pointer
  619.     moveq    #$fffffffd,d0
  620. fdasl_loop
  621.     cmp.b    (a5),d0        ; free?
  622.     beq.s    fdasl_done    ; ... yes
  623.     addq.w    #1,d2        ; next sector group
  624.     addq.l    #3,a5
  625.     cmp.l    a4,a5        ; off end?
  626.     blt.s    fdasl_loop
  627.     moveq    #ERR.DF,d0    ; no empty groups
  628. fdasl_done
  629.     move.l    (sp)+,a4
  630.     rts
  631. ; --------------------------------------------------------------
  632. ; Check all aspects of a drive    V0.3    1985  Tony Tebby
  633. ; Modified for maintenance by CST V 1.17  1986  David Oliver
  634.  
  635. ; write error messages
  636.  
  637. fds_err_mess
  638.     move.l    a1,-(sp)
  639.     lea    fs_mname-2(a2),a1
  640.     move.w    (a1),-(sp)
  641.     move.w    #10,(a1)
  642.     bsr.s    fds_w_mess
  643.     move.w    (sp)+,fs_mname-2(a2)
  644.     move.l    (sp)+,a1
  645. fds_w_mess
  646.     movem.l    d3/a0/a2,-(sp)
  647.     sub.l    a0,a0
  648.     move.w    UT.MTEXT,a2
  649.     jsr    (a2)
  650.     movem.l    (sp)+,d3/a0/a2
  651.     rts
  652.  
  653. ; Check drive set registers and select
  654.  
  655. ; called internally and from SECTIO and FORMT
  656.  
  657. ;       d2  r   current drive running
  658. ;       d4  r   drive required
  659. ;       a2 c p  drive definition block
  660. ;       a3 c p  device linkage block
  661. ;       a4  r   disk control chip address
  662.  
  663. ;       smashes d0,d1,d2,d4,a4
  664.  
  665. fd_ck_sel
  666.     bsr.s    fdc_rset     ; set up registers etc.
  667. fdc_sel
  668.     move.b    d4,d1
  669.     cmp.b    d1,d2        ; is selection required
  670.     bne.l    fd_selct     ; ... yes
  671.     rts
  672.  
  673. fdc_rset
  674.     bsr.l    fd_ahold     ; hold up asynchronous task
  675.     clr.w    d4
  676.     move.b    fs_drivn(a2),d4    ; set drive number required
  677.     move.b    fdd_driv(a3),d2    ; save drive number running
  678.     rts
  679.  
  680. ; check drive for read/write ops
  681.  
  682. ;       d5 c p  read/write flag
  683. ;       a2 c p  drive definition block
  684. ;       a3 c p  device linkage block
  685.  
  686. fd_ck_rw
  687.     movem.l    d1-d5/a0/a1/a4,-(sp) ; save registers
  688.  
  689.     TRAP    #0
  690.     move.w    AV.SR,sr     ;*/68030 move.w sr,-(sp)
  691.     move.w    AV.SR,-(sp)
  692.  
  693.     or.w    #$0700,sr    ; disable interrupts
  694.  
  695.     moveq    #0,d4        ; changed medium not
  696.                 ; permitted
  697.     bsr.s    fdc_rset     ; set registers
  698.     tst.b    fdd_scty(a3)    ; which security level?
  699.     blt.s    fdc_rwerr    ; ... low, only check if it
  700.                 ; has errored
  701.     bgt.s    fdc_rwdc     ; ... high, check if not
  702.                 ; checked
  703.     tst.b    d5        ; ... middling, is it write?
  704.     beq.s    fdc_rwerr    ; ... read, only check if ot
  705.                 ; has errored
  706. fdc_rwdc
  707.     tst.b    fdd_chck-1(a3,d4.l) ; is drive already
  708.                   ; checked?
  709.     beq.s    chk_do        ; ... no, check it
  710. fdc_rwerr
  711.     tst.b    fd_estat(a2)    ; has it errored?
  712.     bra.s    chk_do        ; ... yes, check it
  713.  
  714. ; check drive find track
  715.  
  716.     cmp.b    d4,d2        ; is drive changed?
  717.     beq.s    fdc_ok1        ; ... no
  718.     bsr.s    fdc_sel        ; ... yes, select
  719. ; bne.s     fdc_fe1
  720.     bsr.l    fd_raddr     ; read address
  721. fdc_fe1
  722. ; bne.l     fdc_fe
  723. ; move.b  d1,fd_trakr(a4) ; set track number
  724. fdc_ok1
  725.     bra.l    fdc_exok
  726.  
  727. ; check drive for open
  728.  
  729. fd_ck_op
  730.     movem.l    d1-d5/a0/a1/a4,-(sp) ; save registers
  731.  
  732.     TRAP    #0
  733.     move.w    AV.SR,sr     ;*/68030 move.w sr,-(sp)
  734.     move.w    AV.SR,-(sp)
  735.  
  736.     or.w    #$0700,sr    ; disable interrupts
  737.  
  738.     moveq    #1,d4
  739.     tst.b    fs_files(a2)    ; any files open?
  740.     bne.s    ck_op_rset    ; ... yes
  741.     ror.l    #1,d4        ; ... no, set msb to flag
  742.                 ; change ok
  743. ck_op_rset
  744.     bsr.s    fdc_rset     ; set registers
  745. ; cmp.b    d2,d4    ; is required drive running?
  746. ; beq.s    fdc_operr;... yes, only check if errored
  747.     tst.b    fdd_scty(a3)    ; which security level?
  748.     bgt.s    chk_do        ; ... high, always check
  749.     beq.s    fdc_ck_ck    ; ... middling, check if not
  750.                 ; already checked
  751.     tst.l    d4        ; ... low, only check if
  752.                 ; there are no f open
  753.     bge.s    fdc_ok1        ; ... files open
  754. fdc_ck_ck
  755.     tst.b    fdd_chck-1(a3,d4.w) ; has drive been checked?
  756.     beq.s    chk_do        ; ... no
  757. fdc_operr
  758.     tst.b    fd_estat(a2)    ; has it errored?
  759.     beq.s    fdc_ok1        ; ... no
  760.  
  761. ; drive does require checking
  762.  
  763. chk_do
  764.     bsr.l    fdc_sel        ; select drive
  765.     bsr.l    fd_crdy        ; check if drive has disk in
  766. fdc_est1
  767.     bne.l    fdc_estat    ; ... no
  768.     bsr.l    fdc_check    ; check if disk changed
  769.     blt.s    fdc_est1     ; ... bad
  770.     st    fdd_chck-1(a3,d4.w) ; ... checked
  771.     beq.s    fdc_wprot    ; ... not changed
  772.     tst.l    d4        ; is changed disk ok?
  773.     bge.l    fdc_fo        ; ... no
  774.  
  775.     lea    fd_pend(a2),a1    ; changed disk
  776.     moveq    #fd.npend-1,d0    ; ... clear out pending
  777.                 ; list!!!
  778. fdc_pdclr
  779.     clr.L    (a1)+        ; ensure pending list is
  780.                 ; empty
  781.     dbra    d0,fdc_pdclr
  782.  
  783.     move.l    SV_BTBAS(a6),a1
  784. fdc_sbclr
  785.     moveq    #$fffffff1,d0    ; mask out all odd bits
  786.     and.b    BT_STAT(a1),d0    ; is this a block for this
  787.                 ; drive?
  788.     cmp.b    d0,d6
  789.     bne.s    fdc_sbnxt    ; ... no
  790.     move.b    #BT.EMPTY,BT_STAT(a1) ; ... yes, clear it
  791. fdc_sbnxt
  792.     addq.l    #8,a1        ; next block
  793.     cmp.l    SV_BTTOP(a6),a1
  794.     blt.s    fdc_sbclr
  795.  
  796.     moveq    #0,d5        ; read sectors
  797.     bsr.l    fd_do_ms     ; ... of map
  798.     bne.s    fdc_bad_map    ; ... oops
  799.  
  800.     lea    fd_mdnam(a2),a1    ; transfer medium name
  801.     lea    fs_mname(a2),a0
  802.     move.l    (a1)+,(a0)+
  803.     move.l    (a1)+,(a0)+
  804.     move.l    (a1)+,(a0)+
  805.  
  806. ; check for 40 track in 80 track drive and double sided in
  807. ; single sided drive
  808.  
  809.     move.w    fd_mstrk(a2),d1    ; is sectors/track
  810.     sub.w    fd_mscyl(a2),d1    ; ... the same as
  811.                 ; sectors/cylinder
  812.     beq.s    fdc_40_side    ; ... yes, read from side 0
  813.     moveq    #1,d1        ; ... no, read from side 1
  814. fdc_40_side
  815.     bsr.l    fd_side1     ; set side
  816.     moveq    #2,d1        ; goto track 2
  817.     bsr.l    fd_seek
  818. ; !!!!    bsr  fd_raddr    ; read address
  819. ; bne.s    fdc_bad_map
  820.     subq.b    #2,d1        ; track should be 2
  821.     beq.s    fdc_40_ok
  822.     addq.b    #1,d1        ; was it 1?
  823.     bne.s    fdc_bad_map    ; ... no, give up
  824.     moveq    #1,d1        ; ... yes, 40 on 80 track
  825. fdc_40_ok
  826.     move.b    d1,fdd_wprt-1(a3,d4.w) ; set write protect
  827.                      ; positive or zero
  828.     bsr.l    fd_restore    ; restore drive
  829.  
  830. ; test write protect
  831.  
  832. fdc_wprot
  833.     tst.b    fdd_wprt-1(a3,d4.w) ; is it a 40 track in an
  834.                   ; 80?
  835.     bgt.s    fdc_exok     ; ... yes so implicitly
  836.                 ; write protected
  837.     BSR    fd_wpro
  838.     TST.B    D0
  839.     sne    fdd_wprt-1(a3,d4.w) ; set if it is write
  840.                   ; protected
  841. fdc_exok
  842.     moveq    #0,d0
  843. fdc_rst
  844.     move.w    (sp)+,sr
  845.     movem.l    (sp)+,d1-d5/a0/a1/a4
  846.     tst.l    d0
  847.     rts
  848.  
  849. fdc_bad_map
  850.     clr.l    fd_mhead(a2)    ; set map header to not
  851.                 ; correct format
  852. fdc_estat
  853. fdc_fe
  854.     st    fd_estat(a2)    ; set error occurred
  855.     bsr.l    fd_arel        ; release
  856.     moveq    #ERR.FE,d0
  857.     bra.s    fdc_rst
  858. fdc_fo
  859.     lea    fds_fo_mess(pc),a1
  860.     bsr.l    fds_err_mess
  861.     bra.s    fdc_estat
  862.  
  863. ; check if drive defined / disk changed
  864.  
  865. fdc_check
  866.     BSR    fd_chng
  867.     TST.B    D0
  868.     BNE.S    fdc_name
  869.     MOVEQ    #0,D0        ; signal ok if no change
  870.     RTS
  871.  
  872. ; Check if the name has changed
  873.  
  874. fdc_name
  875.     sf    fd_estat(a2)    ; clear error status
  876.     move.w    d4,d1
  877.     sf    fd_mlgph(a2)    ; set sector zero
  878.                 ; translation to zero
  879.     tst.l    fd_mstrk(a2)    ; is sector allocation set?
  880.     bne.s    fdc_ckd1
  881.     subq.l    #1,fd_mstrk(a2)    ; ensure that first fetch
  882.                 ; does not div check
  883. fdc_ckd1
  884.     sub.w    #$14,sp        ; use stack to read name etc
  885.     move.l    sp,a1
  886.     move.l    fdd_rbeg(a3),-(sp) ; save current read limits
  887.     move.l    #$200-$14,fdd_rbeg(a3) ; number of bytes to
  888.                      ; skip at end of read
  889.     moveq    #0,d1
  890.     moveq    #0,d5
  891.     bsr.l    fd_do_d1     ; and read it
  892.     sne    d0        ; save error return
  893.     move.l    (sp)+,fdd_rbeg(a3) ; reset record read limits
  894.     tst.b    d0        ; test error return
  895.     bne.s    fdc_fe14     ; ... oops
  896.     move.l    sp,a1
  897.     cmp.l    #fd.fmtid,(a1)    ; is it correctly formatted?
  898.     bne.s    fdc_fe14     ; ... no
  899.     lea    fd_mhead(a2),a0    ; check against previous
  900.                 ; header
  901.     moveq    #4,d1
  902. fdc_ckdloop
  903.     cmp.l    (a1)+,(a0)+
  904.     dbne    d1,fdc_ckdloop
  905.     beq.s    fdc_ex14     ; ... name the same
  906.     moveq    #1,d0        ; ... name changed
  907.     bra.s    fdc_ex14
  908. fdc_fe14
  909.     moveq    #ERR.FE,d0    ; ... bad medium
  910. fdc_ex14
  911.     add.w    #$14,sp
  912.     rts
  913. ; --------------------------------------------------------------
  914. ; Find the floppy disc definition block  V0.1
  915. ;  1985  Tony Tebby  QJUMP
  916.  
  917. flp_find
  918.     moveq    #MT.INF,d0    ; find system vars
  919.     trap    #1
  920.     move.l    SV_DDLST(a0),a0    ; ... and linked list of
  921.                 ; directory drivers
  922.     lea    fd_io(pc),a2    ; set entry point for io
  923.                 ; routines
  924. flf_look
  925.     cmp.l    fdd_iolk-fdd_ddlk(a0),a2 ; the right driver?
  926.     beq.s    flf_rts        ; ... yes
  927.     move.l    (a0),a0        ; ... no, try the next
  928.     move.l    a0,d1        ; ... the last?
  929.     bne.s    flf_look
  930.  
  931.     addq.l    #4,sp        ; remove return address
  932. flf_bp
  933.     moveq    #ERR.BP,d0    ; bad, bad, bad
  934. flf_rts
  935.     rts
  936. ; --------------------------------------------------------------
  937. ; Open a file on floppy disk   v0.6  1984  Tony Tebby   QJUMP
  938. ; Modified for CST maintenance V 1.15   1986  David Oliver CST
  939.  
  940. fd_opn
  941.     BSET    #7,fdd_nset(a3)    ; is name set?
  942.     bne.s    fd_opn1
  943.     move.l    #fdd.name,fdd_name(a3) ; set to FLP
  944. fd_opn1
  945.     move.b    fs_drive(a0),d6    ; a2 for phys def and d6 for
  946.                 ; empty slave block
  947.     bsr.l    fd_phys_def
  948.  
  949.     lea    fs_fname(a0),a4
  950.     moveq    #$ffffffdf,d0    ; make second character of
  951.                 ; name UC
  952.     and.l    (a4)+,d0
  953.     cmp.l    #$00042a44,d0    ; is it a '*D..' file name
  954.     bne.s    fdo_normal
  955.     tst.b    fs_files(a2)    ; any files open
  956.     bne.s    fdo_iu        ; ... yes, give up
  957.  
  958.     moveq    #-$33,d5     ; check digit following
  959.     add.b    (a4)+,d5
  960.     bgt.s    fdo_nf1        ; ... greater than 3
  961.     addq.b    #3,d5
  962.     blt.s    fdo_nf1        ; ... less than 0
  963.     bclr    #5,(a4)        ; make next upper case
  964.     cmp.b    #'D',(a4)    ; is it double density
  965.     sne    d6        ; (density flag)
  966.     beq.s    fdo_dset     ; ... yes
  967.     cmp.b    #fd.singl,(a4)    ; is it single density
  968.     bne.s    fdo_nf1
  969. fdo_dset
  970.     st    fd_sflag(a2)    ; say that it is sector
  971.                 ; read/writes
  972.     clr.l    fs_nblok(a0)    ; set sector/side/track 0
  973.     bsr.l    fd_ck_sel    ; select
  974.     move.b    d6,fdd_sden-1(a3,d4.w) ; set density
  975.     clr.b    fdd_wprt-1(a3,d4.w) ; set no protection / not
  976.                   ; 40 on 80
  977.     move.b    d5,fdd_slen-1(a3,d4.w) ; set sector length
  978.     bsr.l    fd_restore    ; ... and restore
  979.     moveq    #0,d0
  980. fdo_arel
  981.     bra.l    fd_arel        ; release asynch tasks
  982.  
  983. fdo_iu
  984.     moveq    #ERR.IU,d0
  985.     rts
  986.  
  987. fdo_normal
  988.     tst.b    fd_sflag(a2)    ; check if in use for sector
  989.                 ; read/writes
  990.     bne.s    fdo_iu
  991.  
  992.     bsr.l    fd_ck_op     ; check for medium changed
  993. fdo_nf1
  994.     bne.s    fdo_nf        ; ... no medium
  995.     bsr.s    fdo_arel     ; release interrupt task
  996.  
  997.     moveq    #1,d0        ; check read only access for
  998.                 ; delete, new and over
  999.     add.b    fs_acces(a0),d0
  1000.     moveq    #%00011001,d1
  1001.     btst    d0,d1
  1002.     beq.s    fdo_a4        ; ro permitted
  1003.     bsr.l    fdio_fro     ; check just the RO flag
  1004.     bne.s    fdo_err        ; ... oops
  1005. fdo_a4
  1006.     lea    fs_spare(a0),a4    ; use spare for io
  1007.     moveq    #fd_deend,d2    ; length of entry
  1008.     move.l    d2,fs_nblok(a0)    ; set start pointer
  1009.     move.l    fd_meodr(a2),fs_eblok(a0) ; set end of file
  1010.                         ; for directory
  1011.     cmp.b    #IO.DIR,fs_acces(a0) ; if open directory
  1012.     beq.l    fdo_dir        ; ... done
  1013.  
  1014.     moveq    #0,d4        ; first empty slot
  1015.     moveq    #0,d5        ; first file number
  1016.     lea    fd_denam+2(a4),a5 ; set up for compare
  1017.  
  1018. fdo_find
  1019.     addq.w    #1,d5        ; next file
  1020.     bsr.l    fdo_read     ; read directory entry
  1021.     bne.s    fdo_derr     ; ... not there
  1022.     tst.l    fd_delen(a4)    ; is entry vacant?
  1023.     beq.s    fdo_empty    ; ... yes
  1024.     lea    fs_fname(a0),a1    ; set address of name
  1025.     move.w    (a1)+,d3     ; and length
  1026.     bsr.l    fdut_cmps    ; and compare against (a5)
  1027.     bne.s    fdo_find     ; ... it was not the same
  1028.     bra    fdo_found    ; ... it was the same
  1029. fdo_empty
  1030.     tst.w    d4        ; have we already found an
  1031.                 ; empty entry?
  1032.     bne.s    fdo_find     ; ... yes
  1033.     move.w    d5,d4        ; ... no, save the pointer
  1034.                 ; to this one
  1035.     bra.s    fdo_find
  1036. fdo_nf
  1037.     moveq    #ERR.NF,d0
  1038. fdo_err
  1039.     rts
  1040. fdo_df
  1041.     moveq    #ERR.DF,d0
  1042.     rts
  1043.  
  1044. ; error reading directory
  1045.  
  1046. fdo_derr
  1047.     cmp.l    #ERR.EF,d0    ; end of file is ok
  1048.     bne    fdo_exit     ; ... anything else is not
  1049.  
  1050. ; file not found
  1051.  
  1052.     move.b    fs_acces(a0),d0    ; is it delete?
  1053.     blt    fdo_ok        ; ... not found is ok
  1054.     subq.b    #IO.NEW,d0    ; is it new or overwrite?
  1055.     blt.s    fdo_nf        ; ... no!
  1056.     moveq    #0,d6        ; genuine new file (eof is
  1057.                 ; zero)
  1058.     tst.w    fd_mfree(a2)    ; any free sectors for new
  1059.                 ; file?
  1060.     beq.s    fdo_df        ; ... no!
  1061.     tst.w    d4        ; was an empty entry found
  1062.     beq.s    fdo_new        ; ... no put the new entry
  1063.                 ; at the end
  1064.  
  1065. fdo_sdir
  1066.     move.w    d4,d5        ; set the file number
  1067.     lsl.l    #fd.desft,d4    ; and calculate the byte
  1068.                 ; position
  1069.     lsl.l    #7,d4        ; ... and so block/byte
  1070.     lsr.w    #7,d4
  1071.     move.l    d4,fs_nblok(a0)    ; set next pointer
  1072.  
  1073. ; new entry at eof or (d4)
  1074.  
  1075. fdo_new
  1076.     move.l    a4,a5        ; create new entry in spare
  1077.                 ; bit
  1078.     move.l    d2,(a5)+     ; length
  1079.     clr.w    (a5)+        ; attribute flags
  1080.     clr.l    (a5)+        ; data space
  1081.     clr.l    (a5)+        ; extra inf
  1082.     moveq    #18,d0        ; copy 19 words (1 word + 36
  1083.                 ; bytes)
  1084.     lea    fs_fname(a0),a1    ; of name
  1085. fdo_name
  1086.     move.w    (a1)+,(a5)+
  1087.     dbra    d0,fdo_name
  1088.  
  1089.     movem.l    a0/d0-d2,-(sp)
  1090.     moveq    #MT.RCLCK,d0    ; get date
  1091.     trap    #1
  1092.  
  1093.     move.l    d1,(a5)+     ; date of last update
  1094.     clr.l    (a5)+
  1095.     move.l    d1,(a5)+     ; backup date (written once)
  1096.  
  1097.     movem.l    (sp)+,a0/d0-d2
  1098.  
  1099.     bsr.s    fdo_write    ; write directory header
  1100.  
  1101.     clr.l    $3C(a4)        ; leave date of 1st update
  1102.  
  1103.     move.l    fs_eblok(a0),fd_meodr(a2) ; reset dir len
  1104.  
  1105.     clr.l    fs_nblok(a0)    ; preset file
  1106.     move.l    d6,fs_eblok(a0)
  1107.     move.w    d5,fs_filnr(a0)
  1108.     bsr.s    fdo_write    ; and write header (never to
  1109.                 ; be updated)
  1110.     bra.s    fdo_exit
  1111.  
  1112. fdo_found
  1113.     move.b    fs_acces(a0),d0    ; check access key
  1114.     blt.s    fdo_del        ; ... delete
  1115.     cmp.b    #IO.NEW,d0    ; new or overwrite?
  1116.     beq.s    fdo_ex        ; ... oops
  1117.     bgt.s    fdo_over     ; ... overwrite
  1118.     move.l    fd_delen(a4),d1    ; find end of file
  1119.     lsl.l    #7,d1        ; ... in block/byte form
  1120.     lsr.w    #7,d1
  1121.     move.w    d5,fs_filnr(a0)    ; set file number
  1122.     move.l    d2,fs_nblok(a0)    ; set next
  1123.     move.l    d1,fs_eblok(a0)    ; set end of file
  1124. fdo_ok
  1125.     moveq    #0,d0
  1126. fdo_exit
  1127.     rts
  1128. fdo_ex
  1129.     moveq    #ERR.EX,d0
  1130.     rts
  1131.  
  1132. ; open directory
  1133.  
  1134. fdo_dir
  1135.     clr.w    fs_fname(a0)
  1136.     bra.s    fdo_ok
  1137.  
  1138. ; overwrite file
  1139.  
  1140. fdo_over
  1141.     move.w    d5,d4        ; use existing entry as
  1142.                 ; empty entry
  1143.     moveq    #fd_deend,d6    ; end of file at end of
  1144.                 ; header
  1145.     bsr    fdo_sdir     ; open as if new
  1146.     bra.s    fd_trun1     ; and truncate
  1147.  
  1148. ; delete file
  1149.  
  1150. fdo_del
  1151.     moveq    #0,d4
  1152.     bsr.l    fdo_trunc    ; truncate to zero
  1153.  
  1154.     lsl.l    #fd.desft,d5    ; get byte position of
  1155.                 ; directory entry
  1156.     lsl.l    #7,d5        ; and so block/byte
  1157.     lsr.w    #7,d5
  1158.     move.l    d5,fs_nblok(a0)
  1159.     moveq    #$40,d0        ; clear $40 bytes
  1160.     lea    $40+fs_spare(a0),a4 ; in spare
  1161. fdd_clr
  1162.     clr.l    -(a4)
  1163.     subq.w    #4,d0
  1164.     bgt.s    fdd_clr
  1165.  
  1166.     bsr.s    fdo_write    ; and write it
  1167.     bra.l    fd_msave     ; and write map
  1168.  
  1169. ; open file read/write utilities
  1170.  
  1171. fdo_read
  1172.     moveq    #IO.FSTRG,d0
  1173.     bra.s    fdo_rdwr
  1174. fdo_write
  1175.     moveq    #IO.SSTRG,d0
  1176. fdo_rdwr
  1177.     move.l    a4,a1
  1178.     bra.l    fd_ior
  1179.  
  1180. ; compare string (a5) against (a1), lengths in -2(a5) and d3
  1181. ; smashes d0,d1,d3
  1182.  
  1183. fdut_cmps
  1184.     cmp.w    -2(a5),d3    ; number of characters the
  1185.                 ; same?
  1186.     bne.s    fdut_rts
  1187.     bra.s    fdut_clend
  1188. fdut_cloop
  1189.     bsr.s    fdut_uc        ; get upper case char
  1190.     move.b    d1,d0
  1191.     bsr.s    fdut_uc        ; and the other
  1192.     cmp.b    d1,d0        ; are they different?
  1193. fdut_clend
  1194.     dbne    d3,fdut_cloop
  1195. fdut_rts
  1196.     rts
  1197. fdut_uc
  1198.     exg    a5,a1        ; swap registers
  1199.     move.b    0(a5,d3.w),d1    ; get char
  1200.     cmp.b    #'a',d1        ; between 'a'
  1201.     blt.s    fdut_uc_rts    ; ... no
  1202.     cmp.b    #'z',d1        ; and 'z'
  1203.     bgt.s    fdut_uc_rts    ; ... no
  1204.     sub.b    #$20,d1
  1205. fdut_uc_rts
  1206.     rts
  1207.  
  1208. ; truncate file d5 to block group d4: remove sectors from map
  1209.  
  1210. fd_trunc
  1211.     bsr.l    fdio_ckro    ; check if read only
  1212.     bne.s    fdut_rts
  1213. fd_trun1
  1214.     move.l    fs_nblok(a0),d4    ; get new end of file
  1215.     move.l    d4,fs_eblok(a0)    ; and set it
  1216.     subq.l    #1,d4        ; and get block holding last
  1217.                 ; byte
  1218.     clr.w    d4
  1219.     swap    d4        ; into d4
  1220.     move.w    d4,d0        ; block?
  1221.     addq.w    #1,d0
  1222.     divu    fd_mallc(a2),d4    ; ... no, block group
  1223.     addq.w    #1,d4
  1224.     swap    d4
  1225.     move.w    d0,d4
  1226.     swap    d4
  1227.     move.w    fs_filnr(a0),d5    ; set file number
  1228.  
  1229. fdo_trunc
  1230.     lea    fd_map(a2),a4    ; bottom of sector map
  1231.     lea    fd_end(a2),a5    ; top of sector map
  1232. fdt_mloop
  1233.     moveq    #0,d0
  1234.     move.b    (a4),d0
  1235.     lsl.w    #8,d0
  1236.     move.b    1(a4),d0
  1237.     ror.l    #4,d0
  1238.     cmp.w    d0,d5        ; is this the right file
  1239.                 ; number?
  1240.     bne.s    fdt_mnext    ; ... no
  1241.     swap    d0
  1242.     lsr.w    #4,d0
  1243.     move.b    2(a4),d0
  1244.     cmp.w    d0,d4        ; is the block off the end
  1245.                 ; of file?
  1246.     bhi.s    fdt_mnext    ; ... no
  1247.     move.b    #$fd,(a4)    ; free the sector
  1248.     move.w    fd_mallc(a2),d0
  1249.     add.w    d0,fd_mfree(a2)    ; ... one more free
  1250.     st    fd_mupdt(a2)    ; map updated
  1251. fdt_mnext
  1252.     addq.l    #3,a4        ; next sector
  1253.     cmp.l    a5,a4        ; last sector?
  1254.     blt.s    fdt_mloop    ; ... no
  1255.  
  1256. ; clear out the slave blocks
  1257.  
  1258.     swap    d4
  1259.     move.b    fs_drive(a0),d1    ; get drive id
  1260.     lsl.b    #4,d1        ; id /
  1261.     addq.b    #1,d1        ; file block
  1262.  
  1263.     move.l    SV_BTBAS(a6),a4    ; get pointer to base of
  1264.                 ; slave block area
  1265. fdt_bloop
  1266.     moveq    #$fffffff1,d0    ; mask out all but drive id
  1267.                 ; and file system flag
  1268.     and.b    BT_STAT(a4),d0    ; from status
  1269.     cmp.b    d0,d1        ; is the the right drive?
  1270.     bne.s    fdt_bnext    ; ... no
  1271.     cmp.w    BT_FILNR(a4),d5    ; is it the right file?
  1272.     bne.s    fdt_bnext    ; ... no
  1273.     cmp.w    BT_BLOCK(a4),d4    ; is it off the end?
  1274.     bhi.s    fdt_bnext    ; ... no
  1275.     move.b    #BT.EMPTY,BT_STAT(a4)
  1276. fdt_bnext
  1277.     addq.l    #8,a4        ; move to next block
  1278.     cmp.l    SV_BTTOP(a6),a4    ; off top?
  1279.     blt.s    fdt_bloop    ; ... no
  1280.  
  1281.     st    fs_updt(a0)    ; file updated
  1282.     moveq    #0,d0        ; and no error
  1283.     rts
  1284. ; --------------------------------------------------------------
  1285. ;  Close a file on floppy disk      1984   Tony Tebby  QJUMP
  1286.  
  1287. fd_clos
  1288.     move.b    fs_drive(a0),d6    ; get drive number
  1289.     bsr.l    fd_phys_def    ; ... and all else
  1290.  
  1291.     tst.b    fd_sflag(a2)    ; was it direct sector IO?
  1292.     beq.s    fdc_flush    ; ... no
  1293.  
  1294.     moveq    #0,d0        ; ... yes
  1295.     move.b    fs_drivn(a2),d0    ; set drive number
  1296.     move.b    #$02,fdd_slen-1(a3,d0.w) ; reset to 512 byte
  1297.                        ; sectors
  1298.     clr.b    fdd_sden-1(a3,d0.w) ; and to double density
  1299.     clr.b    fdd_chck-1(a3,d0.w) ; mark drive not selected
  1300.     clr.l    fd_mhead(a2)    ; drive not previously used
  1301.     sf    fs_files(a2)    ; no files open
  1302.     sf    fd_sflag(a2)    ; normal operation
  1303.     bra.s    fdc_unlk
  1304.  
  1305. fdc_flush
  1306.     moveq    #FS.FLUSH,d0    ; flush out everything
  1307.     bsr.l    fd_ior
  1308.     subq.b    #1,fs_files(a2)    ; ... one fewer files
  1309.  
  1310. fdc_unlk
  1311.     clr.l    fdd_chck(a3)    ; mark drives not selected
  1312.     move.l    a0,-(sp)     ; save base address of
  1313.                 ; channel
  1314.     lea    fs_next(a0),a0    ; and point to next
  1315.     lea    SV_FSLST(a6),a1    ; start of linked list of
  1316.                 ; channels
  1317.     move.w    UT.UNLNK,a2    ; and unlink this one
  1318.     jsr    (a2)
  1319.     move.l    (sp)+,a0     ; restore base address of
  1320.                 ; channel
  1321.     move.w    MM.RECHP,a2    ; and remove
  1322.     jmp    (a2)
  1323. ; --------------------------------------------------------------
  1324. ; IO routines for the floppy disc system  V1.02
  1325. ;  1985  Tony Tebby  QJUMP
  1326.  
  1327. ;       d0   s scratch / error return
  1328. ;       d1 cr  input/output byte
  1329. ;       d2 c s number of bytes to transfer / scratch
  1330. ;       d6   s drive id * 16 + 1
  1331. ;       a0 cr  pointer to channel definition
  1332. ;       a1 crs pointer to read/write buffer
  1333. ;       a3 cr  pointer to linkage block
  1334. ;       a2   s pointer to physical definition
  1335. ;       a4   s pointer to slave block tables
  1336. ;       a5   s
  1337.  
  1338. ; scatter load from floppy disk
  1339.  
  1340. fd_load
  1341.     move.l    a1,-(sp)
  1342.     bsr.l    fd_flush     ; ensure medium is up to
  1343.                 ; date (no write ops)
  1344.     move.l    (sp)+,a1
  1345.     bne.l    fdl_rts
  1346.  
  1347.     move.l    fs_eblok(a0),d7    ; get length
  1348.     lsl.w    #7,d7        ; ... convert to byte form
  1349.     lsr.l    #7,d7
  1350.     moveq    #fs.hdlen,d0
  1351.     sub.l    d0,d7        ; address offset
  1352.     beq.l    fdl_ok
  1353.     add.l    a1,d7        ; end address of load
  1354.     move.l    a1,a4        ; start address of load
  1355.  
  1356.     moveq    #0,d3        ; start looking at track 0
  1357. fdl_tr_loop
  1358.     moveq    #0,d4        ; start at physical sector 0
  1359.                 ; (offset)
  1360. fdl_se_loop
  1361.     move.l    d4,d1        ; set pointer to
  1362.                 ; physical/logical xlate
  1363.     add.b    #fd_mphlg,d1
  1364.     move.b    0(a2,d1.w),d1    ; logical sector in cylinder
  1365.     move.w    d3,d0        ; track * nr of sectors
  1366.     mulu    fd_mscyl(a2),d0    ; (upper end d0=0)
  1367.     add.w    d0,d1        ; logical sector on drive
  1368.  
  1369.     move.l    d1,d2
  1370.     divu    fd_mallc(a2),d2    ; position in map (upper end
  1371.                 ; is posn in group)
  1372.     move.w    d2,d0
  1373.     add.w    d2,d2
  1374.     add.w    d0,d2        ; address in map
  1375.  
  1376.     lea    fd_map(a2),a1
  1377.     add.w    d2,a1
  1378.     move.b    (a1)+,d0     ; get 12 bits of map
  1379.     lsl.w    #8,d0
  1380.     move.b    (a1)+,d0
  1381.     ror.l    #4,d0
  1382.     cmp.w    fs_filnr(a0),d0    ; is the file the same?
  1383.     bne.s    fdl_se_next    ; ... no
  1384.     swap    d0        ; ... yes
  1385.     lsr.w    #4,d0
  1386.     move.b    (a1)+,d0     ; get group number
  1387.     mulu    fd_mallc(a2),d0    ; as sector number
  1388.     swap    d2
  1389.     add.w    d2,d0        ; + sector within group
  1390.     lsl.l    #8,d0
  1391.     add.l    d0,d0        ; gives address from base of
  1392.                 ; load
  1393.  
  1394.     bne.s    fdl_sa1        ; not the first sector
  1395.     move.w    #fs.hdlen,fdd_rbeg(a3) ; first sector includes
  1396.                      ; header
  1397.     lea    (a4),a1
  1398.     bra.s    fdl_ckend
  1399. fdl_sa1
  1400.     lea    -fs.hdlen(a4,d0.l),a1 ; set start address
  1401.                     ; (less header)
  1402. fdl_ckend
  1403.     cmp.l    d7,a1        ; is start of sector off end
  1404.                 ; of file?
  1405.     bge.s    fdl_se_next    ; ... yes
  1406.     add.l    a4,d0
  1407.     add.l    #$200-fs.hdlen,d0
  1408.     sub.l    d7,d0        ; is end of sector off end
  1409.                 ; of file?
  1410.     ble.s    fdl_read     ; ... no
  1411.     move.w    d0,fdd_rend(a3)    ; ... yes, skip bytes at the
  1412.                 ; end
  1413. fdl_read
  1414.     moveq    #0,d5
  1415.     bsr.l    fd_do_sd1    ; read sector
  1416.     sne    d0        ; save error return
  1417.     clr.l    fdd_rbeg(a3)    ; and clear part read flags
  1418.     tst.b    d0
  1419.     bne.l    fdio_fe        ; ... oops
  1420.  
  1421. fdl_se_next
  1422.     addq.l    #1,d4        ; next physical sector
  1423.     cmp.w    fd_mscyl(a2),d4    ; off end?
  1424.     blt.l    fdl_se_loop    ; ... no
  1425.  
  1426.     addq.l    #1,d3        ; next track (cylinder)
  1427.     cmp.w    fd_mtrak(a2),d3    ; off end?
  1428.     blt.l    fdl_tr_loop    ; ... no
  1429.  
  1430.     move.l    d7,a1
  1431. fdl_ok
  1432.     moveq    #0,d0
  1433. fdl_rts
  1434.     rts
  1435.  
  1436. ; rename a file (atomic)
  1437.  
  1438. fd_renam
  1439.     bsr.l    fdio_ckro    ; check read only
  1440.     bne.s    fdrn_rts1
  1441.     move.w    (a1)+,d4
  1442.     subq.w    #5,d4        ; is name too short?
  1443.     bls.s    fd_bn
  1444.     cmp.w    #fs.nmlen+5,d4    ; is name too long?
  1445.     bhi.s    fd_bn        ; ... yes
  1446.     move.l    #$dfdfdfff,d0    ; mask out lc bits from name
  1447.     and.l    (a1)+,d0
  1448.     sub.b    fs_drivn(a2),d0    ; and take away drive number
  1449.     cmp.l    fdd_name(a3),d0    ; is it now FLP0?
  1450.     bne.s    fd_bn        ; ... no, bad
  1451.     cmp.b    #'_',(a1)+    ; is it FLP0_?
  1452.     beq.s    fdrn_1        ; ... yes, good
  1453. fd_bn
  1454.     moveq    #ERR.BN,d0
  1455. fdrn_rts1
  1456.     rts
  1457. fdrn_1
  1458.     lea    fs_spare(a0),a4    ; set up working addresses
  1459.     lea    fd_denam+2(a4),a5
  1460.     move.l    a1,d7        ; and the new name pointer
  1461.     move.w    fs_filnr(a0),d5    ; save the file number
  1462.     clr.w    fs_filnr(a0)    ; and clear it
  1463. fdrn_dup
  1464.     addq.w    #1,fs_filnr(a0)    ; look at next file
  1465.     moveq    #FS.HEADR,d0
  1466.     moveq    #fd_deend,d2
  1467.     move.l    a4,a1        ; use spare area to ...
  1468.     bsr.s    fd_ior        ; read the next header
  1469.     beq.s    fdrn_cname    ; found
  1470.     cmp.w    #ERR.EF,d0    ; end of directory?
  1471.     beq.s    fdrn_sname    ; ... off end
  1472.     bra.s    fdrn_rest
  1473. fdrn_cname
  1474.     move.w    d4,d3        ; set length
  1475.     move.l    d7,a1        ; and new name pointer
  1476.     bsr.l    fdut_cmps    ; compare the strings
  1477.     bne.s    fdrn_dup     ; not the same, try the next
  1478.  
  1479.     moveq    #ERR.EX,d0    ; otherwise error exists
  1480. fdrn_rest
  1481.     move.w    d5,fs_filnr(a0)    ; restore the file number
  1482.     rts
  1483.  
  1484. fdrn_sname
  1485.     lea    fs_fname+fs.nmlen+2(a0),a2 ; set up to clear
  1486.                     ; the name
  1487.     moveq    #fs.nmlen/2,d0
  1488. fdrn_clr
  1489.     clr.w    -(a2)
  1490.     dbra    d0,fdrn_clr
  1491.     move.l    a2,a1        ; save start pointer
  1492.  
  1493.     move.l    d7,a5        ; now set the new filename
  1494.                 ; in channel
  1495.     move.w    d4,(a2)+     ; set length
  1496. fdrn_snlp
  1497.     move.b    (a5)+,(a2)+    ; copy a char at a time
  1498.     sub.w    #1,d4
  1499.     bgt.s    fdrn_snlp
  1500.  
  1501.     move.w    d5,fs_filnr(a0)    ; restore the file number
  1502.     moveq    #fd_denam,d1    ; offset of name in header
  1503.     moveq    #fs.nmlen+2,d2
  1504.     move.b    fs_updt(a0),-(sp) ; rename does not set update
  1505.                 ; flag
  1506.     bsr.s    fd_ihds
  1507.     move.b    (sp)+,fs_updt(a0)
  1508.     rts
  1509.  
  1510. ; internal header set
  1511.  
  1512. fd_ihds
  1513.     moveq    #-1,d0
  1514.  
  1515. ; routine version of fd_io for internal calls from fd_op & fd_cl
  1516.  
  1517. fd_ior
  1518.     movem.l    d0/d2-d7/a4/a5,-(sp)
  1519. fdior_loop
  1520.     movem.l    (sp),d0/d2    ; restore d0/d2
  1521.                 ; operation/count
  1522.     moveq    #1,d3        ; all calls are treated as
  1523.                 ; initial entry
  1524.     bsr.s    fd_io
  1525.     addq.l    #-ERR.NC,d0    ; is it ERR.NC?
  1526.     beq.s    fdior_loop    ; ... yes try again
  1527.     subq.l    #-ERR.NC,d0    ; restore error code
  1528.     addq.l    #4,sp        ; and skip action
  1529.     movem.l    (sp)+,d2-d7/a4/a5
  1530.     rts
  1531. fd_io
  1532.  
  1533. ; set up address of physical definition
  1534.  
  1535.     move.b    fs_drive(a0),d6
  1536.     bsr.l    fd_phys_def
  1537.  
  1538.     tst.b    fd_sflag(a2)    ; is it sector reads?
  1539.     bne.l    fd_sectio
  1540.  
  1541. ; clear the error status
  1542.  
  1543.     move.l    d0,d4        ; save action
  1544.     tst.b    fd_estat(a2)    ; has it errored?
  1545.     beq.s    fdio_action    ; no
  1546.     tst.b    d3        ; initial entry?
  1547.     bne.s    fdio_fe2     ; no, (or internal)
  1548.     bsr.l    fd_ck_rw     ; check the drive again
  1549. fdio_fe2
  1550.     bne.l    fdio_fe        ; not ok
  1551.  
  1552. ; look at action
  1553.  
  1554. fdio_action
  1555.     move.l    d4,d0        ; is it internal header set?
  1556.     blt.l    fd_hdsx        ; ... yes
  1557.     cmp.b    #FS.CHECK,d0    ; is it a file operation?
  1558.     bcs.l    fd_serw        ; ... no, simple serial
  1559.     cmp.b    #FS.TRUNC,d0    ; is it valid?
  1560.     bhi.s    fdio_bp        ; ... no
  1561.  
  1562.     add.w    d0,d0
  1563.     move.w    fd_op_tab-2*FS.CHECK(pc,d0.w),d0 ; branch to
  1564.                           ; file op.
  1565.     jmp    fd_op_tab(pc,d0.w)
  1566. fd_op_tab
  1567.     dc.w    fd_check-fd_op_tab
  1568.     dc.w    fd_flush-fd_op_tab
  1569.     dc.w    fd_posab-fd_op_tab
  1570.     dc.w    fd_posre-fd_op_tab
  1571.     dc.w    fdio_bp-fd_op_tab
  1572.     dc.w    fd_mdinf-fd_op_tab
  1573.     dc.w    fd_heads-fd_op_tab
  1574.     dc.w    fd_headr-fd_op_tab
  1575.     dc.w    fd_load-fd_op_tab
  1576.     dc.w    fd_save-fd_op_tab
  1577.     dc.w    fd_renam-fd_op_tab
  1578.     dc.w    fd_trunc-fd_op_tab
  1579. err_bp
  1580. fdio_bp
  1581.     moveq    #ERR.BP,d0
  1582.     rts
  1583.  
  1584. fd_check
  1585. fd_cf_ok
  1586.     moveq    #0,d0
  1587. fd_cf_rts
  1588.     rts
  1589. fd_flush
  1590.     tst.b    fs_updt(a0)    ; is the file updated?
  1591.     beq.s    fd_cf_ok     ; ... no, done
  1592.  
  1593.     move.l    fs_eblok(a0),d0    ; find end of file
  1594.     lsl.w    #7,d0        ; in block/byte form
  1595.     lsr.l    #7,d0
  1596.  
  1597.     lea    fs_spare(a0),a1    ; put in spare
  1598.     move.l    d0,(a1)
  1599.     moveq    #0,d1        ; write to start of header
  1600.     moveq    #4,d2        ; 4 bytes
  1601.     bsr    fd_ihds        ;*/mend bsr hdsx - set header
  1602.     bne.s    fd_cf_rts
  1603.     move.l    a0,-(sp)
  1604.     moveq    #MT.RCLCK,d0    ; get date
  1605.     trap    #1
  1606.     move.l    (sp)+,a0
  1607.     move.l    d1,(a1)
  1608.     moveq    #fd_deupd,d1    ; put in update date
  1609.     moveq    #4,d2        ; 4 bytes
  1610.     bsr    fd_ihds        ;*/mend bsr hdsx - set header
  1611.     bne.s    fd_cf_rts
  1612.  
  1613.     sf    fs_updt(a0)    ; now not updated
  1614.     bsr.l    fd_msave     ; slave and update map
  1615.     bra.s    fd_cf_ok
  1616.  
  1617. fd_posab
  1618.     bsr.l    fd_spt        ; set pointer
  1619.     bra.s    fd_pos
  1620. fd_posre
  1621.     tst.l    d3        ; do not move pointer if it
  1622.                 ; is re-entry
  1623.     blt.s    fd_pos
  1624.     bsr.l    fd_apt        ; adjust pointer
  1625. fd_pos
  1626.     moveq    #IO.PEND,d0    ; do a pending to prefetch
  1627.     bra.s    fd_ser_1
  1628.  
  1629. fd_mdinf
  1630.     lea    fs_mname(a2),a5    ; copy name
  1631.     move.l    (a5)+,(a1)+
  1632.     move.l    (a5)+,(a1)+
  1633.     move.w    (a5)+,(a1)+
  1634.  
  1635.     move.l    fd_mfree(a2),d1    ; set free/good sectors
  1636.     moveq    #0,d0
  1637.     rts
  1638. fd_save
  1639.     moveq    #IO.SSTRG,d0    ; use send string
  1640. fd_ser_1
  1641.     bra.l    fd_serio
  1642.  
  1643. ; read and set header calls are assumed to complete in one
  1644. ; operation as the header is all in one block
  1645.  
  1646. fd_headr
  1647.     moveq    #IO.FSTRG,d5    ; to read header - read
  1648.                 ; string
  1649.     cmp.w    #fd_deend,d2    ; max length is header
  1650.                 ; length
  1651.     bgt.s    fdio_or
  1652.     move.l    a1,-(sp)     ; save pointer to start
  1653.     bsr.s    fd_head_do    ; read header from directory
  1654.     move.l    (sp)+,a2     ; get start pointer
  1655.     sub.l    #fd_deend,(a2)    ; and take away header
  1656.                 ; length
  1657.     rts
  1658. fdio_or
  1659.     moveq    #ERR.OR,d0    ; ... oops
  1660.     rts
  1661.  
  1662. ; internal set header
  1663.  
  1664. fd_hdsx
  1665.     moveq    #IO.SSTRG,d5    ; send string
  1666.     bra.s    fd_dir_do
  1667.  
  1668. fd_heads
  1669.     moveq    #IO.SSTRG,d5    ; to set header - send
  1670.                 ; string
  1671.     moveq    #$e,d2        ; of 14 bytes
  1672. fd_head_do
  1673.     moveq    #0,d1        ; header starts at first
  1674.                 ; entry
  1675.  
  1676. fd_dir_do
  1677.     moveq    #0,d4        ; get file number
  1678.     move.w    fs_filnr(a0),d4
  1679.     beq.l    fdio_bp        ; ... cant do header of dir
  1680.     move.w    d4,-(sp)     ; save it
  1681.     move.l    fs_eblok(a0),-(sp) ; and eof
  1682.     move.l    fs_nblok(a0),-(sp) ; and next
  1683.     clr.w    fs_filnr(a0)    ; set file zero
  1684.     move.l    fd_meodr(a2),fs_eblok(a0) ; and eof
  1685.                         ; (directory)
  1686.     subq.w    #1,d4
  1687.     lsl.l    #fd.desft,d4    ; and next (64xnumber-1)
  1688.     add.l    d4,d1        ; plus offset from start
  1689.     bsr.l    fd_spt        ; set pointer
  1690.  
  1691.     move.l    d5,d0        ; set action
  1692.     moveq    #0,d1        ; ... nothing moved so far
  1693.     bsr.s    fd_serw        ; and do serial op
  1694.  
  1695.     move.l    (sp)+,fs_nblok(a0) ; restore next
  1696.     move.l    (sp)+,fs_eblok(a0) ; and eof
  1697.     move.w    (sp)+,fs_filnr(a0) ; and file number
  1698.     tst.l    d0
  1699.     rts
  1700. ; --------------------------------------------------------------
  1701. ;  Serial IO operations for floppy disk  1984  Tony Tebby QJUMP
  1702.  
  1703. ;       d0   s scratch / error return
  1704. ;       d1 cr  input/output byte
  1705. ;       d2 c s number of bytes to transfer / scratch
  1706. ;       d3   s action -ve send, 0 check, +ve fetch
  1707. ;        ($a fetch line)
  1708. ;       d4   s block number msw, byte number lsw
  1709. ;       d5   s file number msw, block number lsw
  1710. ;       d6 cr  drive id * 16 + 1
  1711. ;       a0 cr  pointer to channel definition
  1712. ;       a1 crs pointer to read/write buffer
  1713. ;       a3 cr  pointer to linkage block
  1714. ;       a2   s pointer to physical definition
  1715. ;       a4   s pointer to slave block tables
  1716. ;       a5   s
  1717.  
  1718. fdio_ckro
  1719.     move.b    fs_acces(a0),d3    ; check for access
  1720.     subq.b    #IO.SHARE,d3    ; is it share?
  1721.     beq.s    fdio_ro        ; ... yes
  1722.     subq.b    #IO.DIR-IO.SHARE,d3 ; is it dir?
  1723.     beq.s    fdio_ro
  1724. fdio_fro
  1725.     moveq    #0,d3        ; get drive number
  1726.     move.b    fs_drivn(a2),d3
  1727.     tst.b    fdd_wprt-1(a3,d3.w) ; is it write protected?
  1728.     beq.s    fdio_rt1     ; ... no
  1729. fdio_ro
  1730.     moveq    #ERR.RO,d0    ; read only
  1731. fdio_rt1
  1732.     rts
  1733.  
  1734. fd_serw
  1735.     ext.l    d1        ; normal io calls use bottom
  1736.                 ; word of D2
  1737.     ext.l    d2
  1738. fd_serio
  1739.     cmp.b    #IO.SSTRG,d0    ; is operation serial?
  1740.     bhi.l    err_bp
  1741.     moveq    #0,d7        ; set d7 to end of string to
  1742.                 ; be read
  1743.     tst.l    d3        ; is it reentry?
  1744.     bge.s    fd_ser_do    ; ... no
  1745.     sub.l    d1,d7        ; ... yes, take away bytes
  1746.                 ; read
  1747. fd_ser_do
  1748.     subq.b    #IO.EDLIN,d0    ; check operation
  1749. fdio_bpe
  1750.     beq.l    err_bp        ; ... oops
  1751.     blt.s    fdio_fetch    ; ... it's a read
  1752.     bsr.s    fdio_ckro    ; ... it's a write, check
  1753.                 ; read only
  1754.     bne.s    fdio_rt1     ; ... no
  1755.  
  1756. fdio_send
  1757.     moveq    #-1,d3        ; a send operation
  1758.     subq.b    #6-IO.EDLIN,d0    ; which send?
  1759.     beq.s    fdio_bpe     ; ... undefined
  1760.     blt.s    fdio_byte    ; sbyte
  1761.     bgt.s    fdio_string    ; sstrg
  1762.  
  1763. fdio_fetch
  1764.     moveq    #0,d3        ; a fetch, assume pending
  1765.     addq.b    #IO.EDLIN,d0    ; restore key
  1766.     beq.s    fdio_byte    ; ... zero is pending
  1767.     moveq    #$a,d3        ; now assume fline
  1768.                 ; (terminator $a)
  1769.     subq.b    #IO.FLINE,d0
  1770.     beq.s    fdio_string    ; ... it is
  1771.     blt.s    fdio_fbyte    ; ... no, it's byte
  1772.     lsl.w    #8,d3        ; ... no, it's a string
  1773.  
  1774. fdio_string
  1775.     add.l    a1,d7        ; find start of string
  1776.     move.l    d7,-(sp)     ; and save it
  1777.     add.l    d2,d7        ; find end of string
  1778.     bsr.s    fdio_buf
  1779.     move.l    a1,d1        ; find length written
  1780.     sub.l    (sp)+,d1
  1781.     rts
  1782.  
  1783. fdio_fbyte
  1784.     lsl.w    #8,d3        ; lsbyte =0
  1785. fdio_byte
  1786.     move.l    d1,-(sp)     ; put pointer/write byte on
  1787.                 ; stack
  1788.     lea    3(sp),a1     ; ... and point to byte
  1789.     move.l    a1,d7        ; fetch / write 1 byte
  1790.     addq.l    #1,d7
  1791.     bsr.s    fdio_buf
  1792.     move.l    (sp)+,d1     ; get byte read/restore
  1793.                 ; pointer
  1794.     rts
  1795.  
  1796. ;       buffer/unbuffer strings, start a1 end d7
  1797.  
  1798. fdio_buf
  1799.     tst.b    fd_estat(a2)    ; is medium ok?
  1800.     bne.s    fdio_fe        ; ... oops
  1801.     move.l    fs_filnr(a0),d5    ; get file number/block
  1802.                 ; number
  1803.     move.l    fs_nblok(a0),d4    ; get block number/byte
  1804.                 ; number
  1805.     cmp.l    fs_eblok(a0),d4    ; end of file?
  1806.     blt.s    fd_get_block    ; no, get the slave block
  1807.                 ; for this operation
  1808.  
  1809.     bgt.s    fdio_ef        ; yes, pointer is beyond eof
  1810.     tst.b    d3        ; is operation fetch or
  1811.                 ; inquire?
  1812.     blt.s    fdio_eof     ; ... no
  1813. fdio_ef
  1814.     moveq    #ERR.EF,d0    ; end of file
  1815.     rts
  1816. fdio_fe
  1817.     moveq    #ERR.FE,d0    ; file error
  1818. fdio_rts
  1819.     rts
  1820.  
  1821. fdio_eof
  1822.     tst.w    d4        ; the first byte in a new
  1823.                 ; block?
  1824.     beq.s    fdio_ext_block    ; ... yes
  1825.  
  1826. fd_get_block
  1827.     bsr.l    fdb_find     ; get the slave block for
  1828.                 ; this sector
  1829.     bne.s    fdio_rts     ; ... no room (or error)
  1830. ; put prefetch here
  1831.     bra.s    fdio_cblk
  1832.  
  1833. fdio_ext_block
  1834.     cmp.l    a1,d7        ; is there actually anything
  1835.                 ; to go in block?
  1836.     bls.l    fdio_ok        ; ... no so exit
  1837.     bsr.l    fdb_new        ; find space for a new block
  1838.     bne.s    fdio_rts
  1839.     bsr.l    fdas_new     ; find new sector
  1840.     bne.s    fdio_rts
  1841.     move.w    d2,BT_SECTR(a4)    ; set sector number
  1842.     or.b    #BT.TRUE,BT_STAT(a4) ; ... and say it is a
  1843.                    ; true buffer
  1844. fdio_cblk
  1845.     move.l    a4,fs_cblok(a0)    ; ... set pointer to this
  1846.                 ; slave block
  1847.     btst    #BT..ACCS,BT_STAT(a4) ; are contents
  1848.                     ; accessible
  1849.     beq.l    fdb_ncs        ; ... not complete
  1850.  
  1851.     tst.w    d3        ; was it just IO.PEND?
  1852.     beq.s    fdio_ok        ; ... yes, done
  1853.  
  1854.     move.l    a4,d0        ; get address of next block
  1855.     sub.l    SV_BTBAS(a6),d0    ; - base of tables
  1856.     lsl.l    #6,d0        ; * 512/8
  1857.     move.l    d0,a5
  1858.     add.l    a6,a5        ; + base of sysvar
  1859.     add.w    d4,a5        ; + byte pointer
  1860.  
  1861.     tst.w    d3        ; fetch bytes?
  1862.     bgt.s    fdio_get     ; ... yes
  1863.  
  1864. fdio_put
  1865.     cmp.l    a1,d7        ; end of string?
  1866.     bls.s    fdio_pexit
  1867.     move.b    (a1)+,(a5)+    ; put a byte in the block
  1868.  
  1869.     addq.w    #1,d4        ; add 1 to byte pointer
  1870.     btst    #9,d4        ; off end of block?
  1871.     beq.s    fdio_put     ; ... no
  1872.     addq.w    #1,d5        ; add 1 to block
  1873.     add.l    #$fe00,d4    ; add 1 to block, take 512
  1874.                 ; off byte
  1875. fdio_pexit
  1876.     st    fs_updt(a0)    ; mark file updated
  1877.     bsr.s    fdio_swrit    ; set pending op to write
  1878.  
  1879.     cmp.l    fs_eblok(a0),d4    ; is this new eof?
  1880.     blt.s    fdio_sptr    ; ... no
  1881.     move.l    d4,fs_eblok(a0)    ; ... yes, update eof
  1882.     bra.s    fdio_sptr
  1883.  
  1884. fdio_get
  1885.     moveq    #0,d0        ; we need to compare words
  1886. fdio_gloop
  1887.     cmp.l    a1,d7        ; end of string?
  1888.     bls.s    fdio_sptr    ; ... yes
  1889.     cmp.l    fs_eblok(a0),d4    ; beyond end of file?
  1890.     bge.s    fd_ex_eof    ; ... yes
  1891.     move.b    (a5)+,d0     ; get a byte
  1892.     move.b    d0,(a1)+     ; and put it in buffer
  1893.     cmp.w    d0,d3        ; is it terminating
  1894.                 ; character?
  1895.     bne.s    fdio_gnext    ; ... no,
  1896.     move.l    a1,d7        ; reset end pointer to stop
  1897.                 ; loop
  1898. fdio_gnext
  1899.     addq.w    #1,d4        ; add 1 to byte pointer
  1900.     btst    #9,d4        ; off end of block?
  1901.     beq.s    fdio_gloop    ; ... no
  1902.     addq.w    #1,d5        ; add 1 to block
  1903.     add.l    #$fe00,d4    ; add 1 to block, take 512
  1904.                 ; off byte
  1905. fdio_sptr
  1906.     move.l    d4,fs_nblok(a0)    ; set next block / byte
  1907.                 ; pointer
  1908.     cmp.l    a1,d7        ; any more bytes to
  1909.                 ; transfer?
  1910.     bhi.l    fdio_buf     ; ... yes, go back to Buffer
  1911.                 ; to get new slave
  1912.  
  1913.     cmp.w    #$a,d3        ; was it fetch line?
  1914.     bne.s    fdio_ok        ; ... no
  1915.     cmp.b    d0,d3        ; was new line read?
  1916.     beq.s    fdio_ok        ; ... yes
  1917. fdio_bo
  1918.     moveq    #ERR.BO,d0    ; buffer overflow
  1919.     rts
  1920. fdio_ok
  1921.     moveq    #0,d0
  1922.     rts
  1923. fd_ex_eof
  1924.     move.l    d4,fs_nblok(a0)    ; set current block / byte
  1925.                 ; pointer
  1926.     bra.l    fdio_ef
  1927.  
  1928. ; routines to initiate slaving
  1929.  
  1930. fdio_swrit
  1931.     moveq    #BT.UPDT,d0    ; get update bits
  1932.     or.b    d6,d0        ; put drive id in
  1933.     move.b    d0,BT_STAT(a4)    ; set status
  1934.  
  1935.     sub.l    SV_BTBAS(a6),a4    ; calculate slave block
  1936.                 ; pointer
  1937.     lea    fd_pend(a2),a5
  1938.     moveq    #fd.npend-1,d0
  1939. fd_sw_dup
  1940.     cmp.L    (a5)+,a4     ; check for block already in
  1941.                 ; list
  1942.     beq.s    fd_sw_rts    ; ... it is, all is OK
  1943.     dbra    d0,fd_sw_dup
  1944.  
  1945.     lea    fd_pend(a2),a5
  1946.     moveq    #fd.npend-1,d0
  1947. fd_sw_empty
  1948.     tst.L    (a5)+        ; check for hole in list
  1949.     beq.s    fd_sw_set    ; ... found one
  1950.     dbra    d0,fd_sw_empty
  1951.  
  1952.     bsr.l    fd_slavr     ; list is full, empty it
  1953.     lea    fd_pend+4(a2),a5
  1954. fd_sw_set
  1955.     move.L    a4,-(a5)     ; put this block into list
  1956.     st    fdd_pend(a3)    ; and set pending operation
  1957. fd_sw_rts
  1958.     rts
  1959. ; --------------------------------------------------------------
  1960. ; Routines for slaving           V2.1    1984 Tony Tebby QJUMP
  1961. ; Modified for maintenance by CST V 1.15  1986 David Oliver CST
  1962.  
  1963. ; internal forced slaving (from formt/serio)
  1964.  
  1965. fd_slavf
  1966.     tst.b    fdd_pend(a3)
  1967.     beq.s    fd_slrts
  1968. fd_slavr
  1969.     bsr.s    fd_slave
  1970. fd_slavw
  1971.     tst.b    fdd_pend(a3)
  1972.     bne.s    fd_slavw
  1973. fd_slrts
  1974.     rts
  1975.  
  1976. ; external slaving entry
  1977.  
  1978. fd_slave
  1979.     sf    fdd_wait(a3)    ; do not wait
  1980.     st    fdd_pend(a3)    ; force pending operations
  1981.     bsr    fd_do_all
  1982.     bsr    FLUSHALL
  1983.     rts
  1984.  
  1985. ; hold asynch task
  1986.  
  1987. fd_ahold
  1988.     st    fdd_wait(a3)    ; hold up
  1989.     rts
  1990.  
  1991. ; release asynch task
  1992.  
  1993. fd_arel
  1994.     move.b    #fdd.wait,fdd_wait(a3)
  1995.     st    fdd_time(a3)
  1996.     BCLR    #7,fdd_pact(a3)
  1997.     rts
  1998.  
  1999. ; save the map
  2000.  
  2001. fd_msave
  2002.     tst.b    fd_mupdt(a2)    ; is map updated?
  2003.     beq.s    fds_ms_rts
  2004.     st    fd_mwrit(a2)    ; mark map to be written
  2005.     st    fdd_pend(a3)    ; ... force pending ops
  2006.     bsr    fd_do_all
  2007.     bsr    FLUSHALL
  2008.     tst.b    fdd_scty(a3)    ; check security level
  2009.     bgt.s    fd_slavr     ; clear out all
  2010. fds_ms_rts
  2011.     rts
  2012.  
  2013. ; do a read operation directly, a4 is pointer to slave block
  2014.  
  2015. fds_read
  2016.     movem.l    d5/a1,-(sp)
  2017.     moveq    #0,d5        ; do a read operation
  2018.     bsr.l    fd_do_a4
  2019.     movem.l    (sp)+,d5/a1    ; restore the registers
  2020.     rts
  2021. ; --------------------------------------------------------------
  2022. ; Sector IO  (position read/write)    V0.3  1985 Tony Tebby QJUMP
  2023. ; Modified for maintenance by CST V 1.15  1986 David Oliver CST
  2024.  
  2025. fd_sectio
  2026.     subq.b    #IO.FSTRG,d0    ; is it fetch string?
  2027.     beq.s    sio_read
  2028.     subq.b    #IO.SSTRG-IO.FSTRG,d0 ; is it send string?
  2029.     beq.s    sio_write
  2030.     sub.b    #FS.POSAB-IO.SSTRG,d0 ; is it position?
  2031.     beq.l    sio_posab
  2032.     subq.b    #FS.POSRE-FS.POSAB,d0
  2033.     beq.l    sio_posre
  2034.     moveq    #ERR.BP,d0    ; ... no
  2035.     rts
  2036.  
  2037. ; read a sector
  2038.  
  2039. sio_read
  2040.     move.l    a1,-(sp)     ; save pointer
  2041.  
  2042.     lea    fd_read(pc),a5    ; load address of read
  2043.                 ; routine
  2044.  
  2045.     bclr    #1,d2        ; is there a word length at
  2046.                 ; the start?
  2047.     beq.s    sio_set
  2048.  
  2049.     moveq    #0,d0        ; find the drive
  2050.     move.b    fs_drivn(a2),d0
  2051.     move.b    fdd_slen-1(a3,d0.w),d0 ; ... thus sector
  2052.                      ; length
  2053.     clr.w    (a1)
  2054.     bset    d0,(a1)        ; set length * 2
  2055.     lsr.w    (a1)+        ; set length
  2056.     bra.s    sio_length
  2057.  
  2058. ; write a sector
  2059.  
  2060. sio_write
  2061.     move.l    a1,-(sp)     ; save pointer
  2062.     lea    fd_write(pc),a5
  2063.     bclr    #1,d2        ; is there a word length at
  2064.                 ; the start?
  2065.     beq.s    sio_set
  2066.     addq.l    #2,a1        ; skip it
  2067. sio_length
  2068.     tst.w    d2        ; was it just length?
  2069.     beq.s    sio_a1_ok
  2070.  
  2071. ; set up for read/write
  2072.  
  2073. sio_set
  2074.     bsr.l    fd_ck_sel    ; select it and set
  2075.                 ; registers
  2076.  
  2077.     TRAP    #0
  2078.     move.w    AV.SR,sr     ;*/68030 move.w sr,-(sp)
  2079.     move.w    AV.SR,-(sp)
  2080.  
  2081.     or.w    #$0700,sr     ; ... no interrupts
  2082.  
  2083.     move.b    fs_nblok+2(a0),d1 ; set side
  2084.     bsr.l    fd_side1
  2085. ; move.b fs_spare(a0),fd_trakr(a4)    ; set old track
  2086.     move.w    fs_nblok(a0),d1    ; set new track
  2087.     move.b    d1,fs_spare(a0)    ; and save it
  2088.     bsr.l    fd_seekr     ; seek or restore
  2089.     bne.s    sio_fe1
  2090. ; move.b d1,fd_trakr(a4)    ; and set the track we are on!!!
  2091.     move.b    fs_nblok+3(a0),d1 ; read/write sector
  2092.     subq.b    #1,d1        ; ... allowing for internal
  2093.                 ; offset
  2094.     move.b    d1,d6        ; save pointers
  2095.     move.l    a1,d7
  2096.     jsr    (a5)        ; do it
  2097.     TST.B    D2
  2098.     beq.s    sio_fe1        ; ... ok
  2099.     move.b    d6,d1        ; ... bad, restore pointers
  2100.     move.l    d7,a1
  2101.     jsr    (a5)        ; and do again
  2102. sio_fe1
  2103.     sne    d0
  2104.     bsr.l    fd_arel        ; release asynchronous task
  2105.     tst.b    d0
  2106.     beq.s    sio_a1_ok    ; check for errors
  2107. sio_fe
  2108.     lea    fds_rw_mess(pc),a2 ; set error message
  2109.     move.l    a2,d0
  2110.     bset    #31,d0
  2111.     bra.s    sio_a1
  2112. sio_a1_ok
  2113.     moveq    #0,d0
  2114. sio_a1
  2115.     move.l    a1,d1        ; set d1 to difference in a1
  2116.     move.w    (sp)+,sr     ; restore interrupts
  2117.     sub.l    (sp)+,d1
  2118.     rts
  2119.  
  2120. ; set the file position
  2121.  
  2122. sio_posab
  2123.     move.l    d1,fs_nblok(a0)    ; set position
  2124. sio_posre
  2125.     move.l    fs_nblok(a0),d1    ; read position
  2126.     moveq    #0,d0
  2127.     rts
  2128. ; --------------------------------------------------------------
  2129. ; Physical layer for floppy disc    V2.1  1985 Tony Tebby QJUMP
  2130. ; Modified for maintenance by CST. V1.14  1986 David Oliver CST
  2131.  
  2132. ; do all pending write operations
  2133.  
  2134. ;       d6   s  empty status for drive
  2135. ;       a2   s  pointer to physical definition
  2136. ;       a3 c p  pointer to linkage block
  2137.  
  2138. ;       smashes d0,d1,d2,d3,d6,a1,a2,a4
  2139.  
  2140. fd_do_all:
  2141.     MOVEM.L    D0-D3/A1-A2/A4/A6,-(A7)
  2142.     BSR.S    HILF_DO_ALL
  2143.     MOVEM.L    (A7)+,D0-D3/A1-A2/A4/A6
  2144.     RTS
  2145. HILF_DO_ALL:
  2146.     move.l    a5,-(sp)
  2147.     move.b    fdd_driv(a3),d1
  2148.     bsr.l    fd_selct
  2149.     moveq    #$f,d6        ; look at all 16 drives
  2150. fd_do_drive
  2151.     bsr.s    fd_phys_def
  2152.     lea    fdd_ddlk(a3),a1
  2153.     cmp.l    fs_drivr(a2),a1    ; is this the right type of
  2154.                 ; device?
  2155.     bne.s    fd_do_ndrive
  2156.     bsr.s    fd_do_1        ; all ops for this drive
  2157. fd_do_ndrive
  2158.     lsr.w    #4,d6        ; restore drive number
  2159.     dbra    d6,fd_do_drive    ; next drive
  2160.     sf    fdd_pend(a3)    ; clear pending flag
  2161.     bsr.l    fd_arel        ; and reset the timers
  2162.     move.l    (sp)+,a5
  2163.     rts
  2164.  
  2165. ; do write operations for one drive
  2166. ;       d5   s  -1 (write)
  2167. ;       d6 c p  empty status for drive
  2168.  
  2169. ;       smashes d0,d1,d2,d3,d5,a1,a4,a5
  2170.  
  2171. fd_do_1
  2172.     lea    fd_pend(a2),a5    ; get address of pending
  2173.                 ; list
  2174.     moveq    #fd.npend-1,d3    ; max number of pending
  2175.                 ; operations
  2176. fd_do_loop
  2177.     move.L    (a5),d0        ; get slave block offset
  2178.     beq.s    fd_do_map    ; ... no more operations
  2179.     move.l    SV_BTBAS(a6),a4    ; base of sb tables
  2180.     add.L    d0,a4        ; + offset
  2181.     btst    #BT..WREQ,BT_STAT(a4) ; is a write operation
  2182.                     ; required?
  2183.     beq.s    fd_do_lend    ; ... no (so why is it in
  2184.                 ; the list?)
  2185.     moveq    #-1,d5        ; set write operation
  2186.     bsr.s    fd_do_a4     ; ... and do it
  2187. fd_do_lend
  2188.     clr.L    (a5)+        ; clear pending
  2189.     dbra    d3,fd_do_loop
  2190. fd_do_map
  2191.     tst.b    fd_mwrit(a2)    ; is map required to be
  2192.                 ; written?
  2193.     beq.s    fd_do_rts
  2194.     sf    fd_mwrit(a2)    ; clear flag
  2195.     bsr.l    fd_ck_rw     ; check read/write ok
  2196.     bne.s    fd_do_rts
  2197.  
  2198.     addq.l    #1,fd_mdupd(a2)    ; increment update count
  2199. fd_do_mw
  2200.     moveq    #-1,d0        ; write sectors
  2201. fd_do_ms
  2202.     lea    fd_mhead(a2),a1    ; set address to save map
  2203.                 ; from
  2204.     moveq    #0,d3        ; put sector 0
  2205. fdp_msloop
  2206.     move.l    d3,d1
  2207.     MOVEM.L    A1,-(A7)     ; save pointer to map
  2208.     bsr.s    fd_do_d1     ; (number in d1)
  2209.     MOVEM.L    (A7)+,A1     ; restore pointer to map
  2210.     TST.B    D0
  2211.     bne.s    fd_do_mw
  2212.     ADD.L    #512,A1        ; point to next sector of
  2213.                 ; map
  2214.     addq.l    #1,d3        ; next sector number in d3
  2215.     cmp.b    #3,d3
  2216.     blt.s    fdp_msloop
  2217.     sf    fd_mupdt(a2)    ; say map is up to date
  2218. fd_do_rts
  2219.     rts
  2220.  
  2221. ; set physical definitions
  2222. ;       d6 c r  drive id / empty status for drive
  2223. ;       a2   r  address of physical definition block for drive
  2224.  
  2225. fd_phys_def
  2226.     ext.w    d6
  2227.     lsl.w    #2,d6
  2228.     lea    SV_FSDEF(a6),a2
  2229.     move.l    0(a2,d6.w),a2
  2230.     lsl.w    #2,d6
  2231.     addq.w    #BT.EMPTY,d6
  2232.     rts
  2233.  
  2234. ; read or write one sector using slave blocks
  2235. ;       d5 c p  =0 read, <>0 write
  2236. ;       d6 c p  empty status for drive
  2237. ;       a1   s  pointer to read/write buffer
  2238. ;       a2   p  pointer to physical definition block
  2239. ;       a3   p  pointer to linkage block
  2240. ;       a4 c p  pointer to slave block tables
  2241.  
  2242. ;       smashes d0,d1,d2,a1
  2243.  
  2244. fd_do_a4
  2245.     move.l    a4,d0        ; calculate base of block
  2246.     sub.l    SV_BTBAS(a6),d0
  2247.     lsl.l    #6,d0
  2248.     lea    0(a6,d0.l),a1    ; in a1
  2249.  
  2250.     move.w    BT_SECTR(a4),d1    ; set sector number
  2251.     mulu    fd_mallc(a2),d1
  2252.     moveq    #0,d0        ; plus block MOD alloc
  2253.     move.w    BT_BLOCK(a4),d0
  2254.     divu    fd_mallc(a2),d0
  2255.     swap    d0
  2256.     add.w    d0,d1
  2257.     bsr.s    fd_do_sd1
  2258.     beq.s    fd_do_ok
  2259.  
  2260.     and.b    #BT.NACTN,BT_STAT(a4) ; clear actions but do
  2261.                     ; not set access
  2262.     lea    fds_rw_mess(pc),a1 ; write message
  2263.     bsr.l    fds_err_mess
  2264.     move.b    #1,fd_estat(a2)    ; and set status read/write
  2265.                 ; failure
  2266.     rts
  2267.  
  2268. fd_do_ok
  2269.     move.b    d6,BT_STAT(a4)    ; set status
  2270.     bset    #BT..ACCS,BT_STAT(a4) ; ... ok
  2271.     moveq    #0,d0
  2272.     rts
  2273.  
  2274. ; select and do one read/write
  2275.  
  2276. fd_do_sd1
  2277.     bsr.l    fd_ck_rw     ; select (and hold)
  2278.     bne.s    fd_do_rts    ; (released on error)
  2279.  
  2280. ; do one read/write
  2281.  
  2282. fd_do_d1
  2283.     clr.w    -(sp)        ; clear failure count
  2284. fd_do_again
  2285.     movem.l    d1/d3/a2/a4/a5,-(sp) ; save registers
  2286.     move.l    a1,a5        ; save BUffer pointer
  2287.     ext.l    d1
  2288.     divu    fd_mscyl(a2),d1    ; get track
  2289.     move.w    d1,-(sp)
  2290.     move.w    d1,d3
  2291.     mulu    fd_msoff(a2),d3    ; get track*offset
  2292.     clr.w    d1
  2293.     swap    d1
  2294.     move.b    fd_mlgph(a2,d1.w),d1 ; and sector/side
  2295.     bclr    #7,d1
  2296.     sne    d2        ; side
  2297.     add.w    d3,d1        ; sector
  2298.     divu    fd_mstrk(a2),d1
  2299.     swap    d1        ; MOD mscyl
  2300.     move.w    d1,-(sp)
  2301.  
  2302.     moveq    #1,d1
  2303.     and.w    d2,d1
  2304.     bsr.l    fd_side1     ; set side
  2305.     move.w    2(sp),d1     ; get track
  2306. ;   cmp.b   fd_trakr(a4),d1 is it the right track?
  2307. ;   beq.s   fd_do_rw
  2308.     bsr.l    fd_seek40
  2309.  
  2310. fd_do_rw
  2311.  
  2312.     TRAP    #0
  2313.     move.w    AV.SR,sr     ;*/68030 move.w sr,-(sp)
  2314.     move.w    AV.SR,-(sp)
  2315.  
  2316.     or.w    #$0700,sr    ; disable interrupts
  2317.  
  2318.     moveq    #$1f,d1        ; get physical sector (-1)
  2319.     and.w    2(sp),d1
  2320.     tst.b    d5
  2321.     beq.s    fd_do_rd
  2322.     bsr.l    fd_write     ; write
  2323.     bra.s    fd_do_rint
  2324. fd_do_rd
  2325.     bsr.l    fd_read
  2326. fd_do_rint
  2327.     move.w    (sp)+,sr     ; restore interrupts
  2328.     movem.l    (sp)+,d0/d1/d3/a2/a4/a5 ; remove 4 bytes from
  2329.                       ; sp and restore regs
  2330.     move.b    d2,d0        ; get error return
  2331.     ble.s    fd_do_x8     ; operation ok or timed out
  2332. ; subq.b #1,d2        ; seek error?
  2333. ; bne.s    fd_inc_fail ;... not a seek error
  2334. ; tst.b    (sp)        ;... seek error, first one?
  2335. ; beq.s    fd_inc_fail ;... yes
  2336.  
  2337. fd_inc_fail
  2338. ; addq.b #1,(sp)        ;increment failure count
  2339. ; cmp.b    #3,(sp)
  2340. ; ble.l    fd_do_again    ;and retry up to three times
  2341.     NOP
  2342.  
  2343. fd_do_x8
  2344.     bsr.l    fd_arel        ; release asynch task
  2345.     addq.l    #2,sp        ; remove failure count
  2346.  
  2347.     tst.b    d0        ; and test error return
  2348.  
  2349.     rts
  2350. ; --------------------------------------------------------------
  2351. ; Set the next byte pointers     1985  Tony Tebby   QJUMP
  2352. ;
  2353. ;       d0   s  scratch
  2354. ;       d1 cr   byte pointer to file (returned absolute)
  2355. ;       a0 c p  channel definition block
  2356.  
  2357. ; adjust pointer by d1
  2358.  
  2359. fd_apt
  2360.     move.l    fs_nblok(a0),d0    ; get current pointer
  2361.  
  2362. ; calculate pointer
  2363.  
  2364. fd_cpt
  2365.     lsl.w    #7,d0        ; in byte pointer form
  2366.     lsr.l    #7,d0
  2367.     sub.l    #fd_deend,d0    ; relative to start
  2368.     add.l    d0,d1        ; add to offset
  2369.     bvs.s    fd_pt_eof
  2370.  
  2371. ; set pointer to d1
  2372.  
  2373. fd_spt
  2374.     move.l    d1,d0        ; preserve updated address
  2375.                 ; (in d1)
  2376.     bmi.s    fd_pt_bof    ; ... it's off the beginning
  2377.     add.l    #fd_deend,d0
  2378.     bvs.s    fd_pt_eof
  2379.     asl.l    #6,d0        ; shift most of the way
  2380.     bvs.s    fd_pt_eof    ; ... to check for sign
  2381.                 ; change
  2382.     add.l    d0,d0        ; and the last little bit
  2383.     lsr.w    #7,d0        ; ... it's now in block/byte
  2384.                 ; form
  2385.     cmp.l    fs_eblok(a0),d0    ; but is it within the file?
  2386.     ble.s    fd_setnb     ; ... yes
  2387. fd_pt_eof
  2388.     moveq    #0,d1        ; if off the end of file
  2389.     move.l    fs_eblok(a0),d0    ; ... set it to eof
  2390.     bra.s    fd_cpt
  2391. fd_pt_bof
  2392.     moveq    #fd_deend,d0    ; beginning of file is at
  2393.                 ; end of header
  2394.     moveq    #0,d1        ; but appears to be zero
  2395. fd_setnb
  2396.     move.l    d0,fs_nblok(a0)
  2397.     rts
  2398. ; --------------------------------------------------------------
  2399. ; Format medium. Changed in some aspects to support amiga
  2400. ; hardware
  2401. ; at increased speed.
  2402. ; --------------------------------------------------------------
  2403. ; Format procedure for floppy disks  V2.3    1985  Tony Tebby
  2404. ;
  2405. ;       d1 cr   drive number / good sectors
  2406. ;       d2  r   total sectors
  2407. ;       a0 c    medium name
  2408. ;       a3 c    linkage block
  2409.  
  2410. fdf.group equ    3
  2411.  
  2412. fd_format
  2413.     move.l    a0,a5        ; save call params
  2414.     move.w    d1,d6
  2415.  
  2416.     move.l    a3,-(sp)     ; save base of linkage block
  2417.     moveq    #MT.ALCHP,d0    ; and allocate space
  2418.     move.l    #fd_end+$200,d1    ; $28+3*512 bytes + one
  2419.                 ; sector
  2420.     moveq    #0,d2
  2421.     trap    #1
  2422.     move.l    (sp)+,a3
  2423.     tst.l    d0
  2424.     beq.s    fdf_set        ; ... ok
  2425.     rts    ...        ; oops
  2426. fdf_set
  2427.  
  2428.     TRAP    #0
  2429.     move.w    AV.SR,sr
  2430.     move.w    AV.SR,-(sp)    ;*/68030  move.w sr,-(sp)
  2431.  
  2432.     or.w    #$0700,sr    ; disable interrupts
  2433.  
  2434.     bsr.l    fd_slavf     ; do all pending ops and
  2435.                 ; stop interrupt task
  2436.     move.l    a0,a2        ; set base of pseudo
  2437.                 ; definition block
  2438.     move.b    d6,fs_drivn(a2)    ; set drive number
  2439.     move.l    #$90009,-(sp)    ; ... and set number of
  2440.                 ; sectors track/cylinder
  2441.     bsr.l    fd_ck_sel    ; select (and hold) drive,
  2442.                 ; set registers
  2443.     sf    fdd_wprt-1(a3,d6.w) ; clear 40/80 flag
  2444.     sf    fdd_chck-1(a3,d6.w) ; clear the checked flag
  2445.  
  2446.     bsr.l    fd_restore    ; and restore drive
  2447.  
  2448.     moveq    #0,d4
  2449.     move.b    fdd_ntrk(a3),d4    ; get number of tracks
  2450.     bne.s    fdf_sets     ; ... it is set
  2451.     moveq    #80,d4        ; 80 track on amiga
  2452.  
  2453. ; set number of sides
  2454.  
  2455. fdf_sets
  2456.     cmp.w    #5+10,(a5)    ; is name at least 11
  2457.                 ; characters long?
  2458.     ble.s    fdf_chkt     ; ... no
  2459.     cmp.b    #'*',2+5+10(a5)    ; is it forced single sided?
  2460.                 ; (11th character=*)
  2461.     beq.s    fdf_blank    ; ... yes
  2462.  
  2463. ; check number of tracks
  2464.  
  2465. fdf_chkt
  2466.     lsl.w    (sp)        ; increment number of sides
  2467.                 ; on amiga
  2468.  
  2469. ; set up blank map
  2470.  
  2471. fdf_blank
  2472.     move.w    #$5ff,d0     ; fill medium header buffer
  2473.                 ; with $ff
  2474.     lea    fd_mhead+$600(a0),a1
  2475. fdf_bloop
  2476.     st    -(a1)
  2477.     dbra    d0,fdf_bloop
  2478.  
  2479.     move.l    #'QL5A',(a1)+
  2480.  
  2481.     move.w    (a5)+,d0     ; length of medium name
  2482.     addq.l    #5,a5        ; less fdkn_
  2483.     subq.w    #5,d0
  2484.     moveq    #10,d1
  2485.     sub.w    d0,d1        ; >10?
  2486.     bge.s    fdf_snend
  2487.     moveq    #9,d0        ; yes, take first 10
  2488. fdf_snloop
  2489.     move.b    (a5)+,(a1)+    ; copy it into map
  2490. fdf_snend
  2491.     dbra    d0,fdf_snloop
  2492.  
  2493.     bra.s    fdf_spend
  2494. fdf_sploop
  2495.     move.b    #' ',(a1)+    ; now pad with spaces
  2496. fdf_spend
  2497.     subq.w    #1,d1
  2498.     bge.s    fdf_sploop
  2499.  
  2500.     move.w    SV_RAND(a6),(a1)+ ; random number
  2501.     clr.l    (a1)+        ; update count
  2502.     move.w    (sp),d1        ; calculate total sectors
  2503.     mulu    d4,d1
  2504.     move.w    d1,(a1)        ; number of sectors
  2505.     subq.w    #6,(a1)+     ; (6 taken)
  2506.     move.w    d1,(a1)+     ; good
  2507.     move.w    d1,(a1)+     ; total
  2508.     move.w    2(sp),(a1)+    ; sectors per track
  2509.     move.w    (sp),(a1)+    ; sectors per cylinder
  2510.     move.w    d4,(a1)+     ; number of tracks
  2511.     move.w    #fdf.group,(a1)+    ; sectors per allocation
  2512.                 ; group
  2513.     move.l    #fd_deend,(a1)+    ; length of directory
  2514.     moveq    #18,d0
  2515.     lea    fdf_9trans(pc),a5 ; set sector translate
  2516.                 ; tables for amiga
  2517. fdf_stran
  2518.     move.w    (a5)+,(a1)+
  2519.     dbra    d0,fdf_stran
  2520.  
  2521. ; now format and check all the tracks
  2522.  
  2523.     moveq    #0,d6        ; start at track 0
  2524.     move.w    (sp),d4        ; number of sectors /
  2525.                 ; cylinder
  2526.     lea    fd_map(a0),a5    ; set address of map
  2527. fdf_tr_loop
  2528.     moveq    #0,d7        ; side 1
  2529.     bsr.s    fdf_fmt_chk    ; format and check
  2530. fdf_tr_s0
  2531.     moveq    #1,d7        ; side 0
  2532.     bsr.s    fdf_fmt_chk    ; format and check
  2533.     moveq    #$fffffffd,d0    ; ... good cylinder, mark
  2534.                 ; vacant
  2535. fdf_mset
  2536.     moveq    #0,d1        ; set number of map entries
  2537.                 ; per cylinder
  2538.     move.w    d4,d1
  2539.     divu    #fdf.group,d1
  2540. fdf_msloop
  2541.     move.b    d0,(a5)        ; and set all good or bad
  2542.     addq.l    #3,a5
  2543.     subq.w    #1,d1
  2544.     bgt.s    fdf_msloop
  2545.  
  2546.     addq.w    #1,d6        ; move on one track
  2547.     cmp.w    fd_mtrak(a0),d6    ; end of map?
  2548.     blt.s    fdf_tr_loop    ; ... no
  2549.  
  2550.     lea    fd_map(a0),a5
  2551.     cmp.l    #$fdfffffd,(a5)    ; are the first two groups
  2552.                 ; free?
  2553.     bne.s    fdf_ff        ; ... no
  2554.  
  2555.     move.w    #$f800,(a5)+    ; set it to medium header /
  2556.                 ; directory
  2557.     clr.l    (a5)
  2558.  
  2559.     lea    (a0),a2        ; set pseudo definition
  2560.                 ; block pointer
  2561.     bsr.l    fd_do_mw     ; write map sectors
  2562.     bne.s    fdf_ff        ; ... oops
  2563.     moveq    #0,d0
  2564.     bra.s    fdf_exit
  2565.  
  2566. ; error returns
  2567.  
  2568. fdf_ff
  2569.     moveq    #ERR.FF,d0
  2570. fdf_exit
  2571.     bsr.l    fd_dskcng    ; force a disc change signal
  2572.                 ; from drive
  2573.     st    fdd_driv(a3)    ; change the drive so next
  2574.                 ; open reads header
  2575.     bsr.l    fd_arel        ; release asynch tasks
  2576.     move.l    fd_mgood(a0),d7    ; save sector counts
  2577.     move.l    d0,d4        ; save error flag
  2578.     moveq    #MT.RECHP,d0    ; return space to common
  2579.                 ; heap
  2580.     trap    #1
  2581.     move.l    d4,d0        ; restore error flag
  2582.     move.w    d7,d2        ; set sector counts
  2583.     swap    d7
  2584.     move.w    d7,d1
  2585.     addq.l    #4,sp
  2586.     move.w    (a7)+,sr
  2587.     rts
  2588.  
  2589. ; subroutine to format and write a track
  2590.  
  2591. fdf_fmt_chk
  2592.     bsr.s    fdf_sk_trk    ; seek and write track
  2593.     bne.s    fdf_wr_err    ; ... oops
  2594.     moveq    #0,d5
  2595. fdf_read
  2596.     move.b    d5,d1        ; read next sector
  2597.     lea    fd_end(a0),a1    ; ... into spare bit at end
  2598.     bsr.l    fd_read
  2599.     bne.s    fdf_rd_err    ; ... oops
  2600.     addq.w    #1,d5
  2601.     cmp.b    #9,d5        ; last?
  2602.     blt.s    fdf_read     ; ... no
  2603.  
  2604. ;     movem.l  d0/a0,-(a7)     ; temporary aberration
  2605. ;     move.l     #0,a0
  2606. ;     move.l     #$00010000+'. ',d0 ; signal OK
  2607. ;     bsr     IOD0
  2608. ;     movem.l  (a7)+,d0/a0
  2609.  
  2610.     rts            ; all ok
  2611.  
  2612. ; read / verify failed
  2613.  
  2614. fdf_rd_err
  2615. ;     movem.l  d0/a0,-(a7)     ; temporary aberration
  2616. ;     move.l     #0,a0
  2617. ;     move.l     #$00010000+'R ',d0 ; signal read error
  2618. ;     bsr     IOD0
  2619. ;     movem.l  (a7)+,d0/a0
  2620.  
  2621.     addq.l    #4,sp        ; remove return
  2622.     moveq    #$fffffffe,d0    ; bad track
  2623.     sub.w    d4,fd_mfree(a0)    ; decrement sector counts
  2624.     sub.w    d4,fd_mgood(a0)
  2625.     bra    fdf_mset     ; and set map entries
  2626.  
  2627. ; write track failed
  2628.  
  2629. fdf_wr_err
  2630. ;     movem.l  d0/a0,-(a7)     ; temporary aberration
  2631. ;     move.l     #0,a0
  2632. ;     move.l     #$00010000+'W ',d0 ; signal write error
  2633. ;     bsr     IOD0
  2634. ;     movem.l  (a7)+,d0/a0
  2635.  
  2636.     addq.l    #4,sp        ; remove return
  2637.     bra    fdf_ff        ; format failed (short?)
  2638. ; write a track
  2639.  
  2640. fdf_sk_trk
  2641.     move.b    d6,d1        ; seek to track
  2642.     bsr.l    fd_seek
  2643. fdf_track
  2644.     move.b    d7,d1        ; select side in d1
  2645.     bsr.l    fd_side
  2646.  
  2647.     bsr.l    fd_ftrack
  2648.  
  2649. fdf_trkx
  2650.     tst.b    d0
  2651.  
  2652.     rts
  2653.  
  2654. fdf_9trans
  2655.     dc.w    5
  2656.     dc.b    $00,$03,$06,$01,$04,$07,$02,$05,$08
  2657.     dc.b    $80,$83,$86,$81,$84,$87,$82,$85,$88
  2658.     dc.b    $00,$03,$06,$01,$04,$07,$02,$05,$08
  2659.     dc.b    $09,$0c,$0f,$0a,$0d,$10,$0b,$0e,$11
  2660.  
  2661. ; --------------------------------------------------------------
  2662. ;
  2663. ;      BASIC extensions start here
  2664. ;
  2665. ; --------------------------------------------------------------
  2666. prog_use
  2667.     moveq    #$00,d5
  2668.     bra.s    xxx_use
  2669.  
  2670. data_use
  2671.     moveq    #$04,d5
  2672.     bra.s    xxx_use
  2673.  
  2674. dest_use
  2675.     moveq    #$08,d5
  2676.     bra.s    xxx_use
  2677.  
  2678. spl_use
  2679.     move.w    #$88,d5
  2680.  
  2681. xxx_use
  2682.     bsr.l    ut_stos        ; get a string
  2683.     bne.s    xxx_rts        ; ... oops
  2684.     cmp.w    #30,0(a6,a1.l)    ; <=30 characters long
  2685.     bgt    flp_bp        ; ... oops
  2686.  
  2687.     moveq    #MT.INF,d0    ; find the system variables
  2688.     trap    #1
  2689.     lea    SV_PROGD(a0),a0    ; and set the pointers to
  2690.                 ; the defaults
  2691.     move.w    d5,d0
  2692.     andi.b    #$7F,d0
  2693.     move.l    0(a0,d0.w),a4
  2694.  
  2695.     move.w    0(a6,a1.l),d1
  2696.     addq.l    #2,a1
  2697.     move.w    d1,(a4)+
  2698.  
  2699.     tst.b    d5
  2700.     bmi.s    xxx_dec
  2701.  
  2702.     lea    -1(a1,d1.w),a2
  2703.     cmpi.b    #'_',0(a6,a2.l)
  2704.  
  2705.     beq.s    xxx_dec
  2706.  
  2707.     cmpi.w    #30,d1
  2708.     beq    flp_bp        ; name too long
  2709.  
  2710.     move.b    #'_',0(a4,d1.w)    ; append underline
  2711.  
  2712.     addq.w    #1,d1
  2713.     move.w    d1,-2(a4)    ; increment length
  2714.     subq.w    #1,d1
  2715.  
  2716.     bra.s    xxx_dec
  2717.  
  2718. xxx_lup
  2719.     move.b    0(a6,a1.l),d0
  2720.     addq.l    #1,a1
  2721.     move.b    d0,(a4)+
  2722.  
  2723. xxx_dec
  2724.     dbra    d1,xxx_lup
  2725.  
  2726.     moveq    #0,d0
  2727.  
  2728. xxx_rts
  2729.     rts
  2730.  
  2731. prog_d$
  2732.     moveq    #0,d5
  2733.     bra.s    xxx_d$
  2734.  
  2735. data_d$
  2736.     moveq    #4,d5
  2737.     bra.s    xxx_d$
  2738.  
  2739. dest_d$
  2740.     moveq    #8,d5
  2741.     bra.s    xxx_d$
  2742.  
  2743. spl_d$
  2744.     moveq    #8,d5
  2745.  
  2746. xxx_d$
  2747.     cmp.l    a3,a5
  2748.     bne    flp_bp        ; ... oops
  2749.  
  2750.     moveq    #MT.INF,d0    ; find the system variables
  2751.     trap    #1
  2752.     lea    SV_PROGD(a0),a0    ; and set the pointers to
  2753.                 ; the defaults
  2754.     move.l    0(a0,d5),a4
  2755.  
  2756.     move.w    (a4)+,d4
  2757.  
  2758.     move.l    d4,d1
  2759.     addq.l    #1,d1
  2760.     and.b    #$FE,d1
  2761.     move.w    BV.CHRIX,a2
  2762.     jsr    (a2)
  2763.  
  2764.     sub.l    d1,BV_RIP(a6)
  2765.     move.l    BV_RIP(a6),a1
  2766.  
  2767.     move.w    d4,0(a6,a1.l)
  2768.     addq.l    #2,a1
  2769.     bra.s    xxx_dec$
  2770.  
  2771. xxx_lup$
  2772.     move.b    (a4)+,d0
  2773.     move.b    d0,0(a6,a1.l)
  2774.     addq.l    #1,a1
  2775.  
  2776. xxx_dec$
  2777.     dbra    d4,xxx_lup$
  2778.  
  2779.     move.l    BV_RIP(a6),a1
  2780.     moveq    #1,d4
  2781.     moveq    #0,d0
  2782.     rts
  2783.  
  2784. ; Set the name of the floppy disk system  1985 Tony Tebby QJUMP
  2785. ;       bra.s   dev_use        * Go to it.        ** 1.17 **
  2786.  
  2787. flp_use
  2788.     lea    fd_io(pc),a4    ; Get entry point for io
  2789.                 ; routines       ** 1.17 **
  2790. dev_use
  2791.     bsr.l    ut_stos        ; get a string
  2792.     bne.s    flp_rts        ; ... oops
  2793.     subq.w    #3,0(a6,a1.l)    ; 3 characters long
  2794.     bne.s    flp_bp        ; ... oops
  2795.     move.l    2(a6,a1.l),d6    ; get new name
  2796.     and.l    #$5f5f5f00,d6    ; in upper case
  2797.     add.b    #'0',d6        ; ending with '0'
  2798.  
  2799.     moveq    #MT.INF,d0    ; find system vars
  2800.     trap    #1
  2801.     move.l    SV_DDLST(a0),a0    ; ... and linked list of
  2802.                 ; directory drivers
  2803.  
  2804. flp_look
  2805.     cmp.l    fdd_iolk-fdd_ddlk(a0),a4 ; the right driver?
  2806.                        ;    ** 1.17 **
  2807.     beq.s    flp_set        ; ... yes
  2808.     move.l    (a0),a0        ; ... no, try the next
  2809.     move.l    a0,d1        ; ... the last?
  2810.     bne.s    flp_look
  2811. flp_bp
  2812.     moveq    #ERR.BP,d0
  2813. flp_rts
  2814.     rts
  2815. flp_set
  2816.     move.l    d6,fdd_name-fdd_ddlk(a0) ; set new name
  2817.     rts
  2818.  
  2819.     ifd    extras
  2820.  
  2821. ; --------------------------------------------------------------
  2822. flp_opt
  2823.     move.w    CA.GTINT,a2
  2824.     jsr    (a2)
  2825.     bne.s    flo_rts
  2826.     subq.w    #1,d3
  2827.     blt.s    flo_rts
  2828.     bsr    flp_find
  2829.     movem.w    0(a6,a1.l),d4/d5/d6 ; get 3 parameters
  2830.  
  2831.     subq.b    #1,d4
  2832.     move.b    d4,fdd_scty-fdd_ddlk(a0) ; set security level
  2833.  
  2834.     subq.w    #1,d3
  2835.     blt.s    flo_rts
  2836.     move.b    d5,fdd_stim-fdd_ddlk(a0) ; set start up time
  2837.  
  2838.     subq.w    #1,d3
  2839.     blt.s    flo_rts
  2840.     move.b    d6,fdd_ntrk-fdd_ddlk(a0) ; set number of
  2841.                        ; tracks
  2842. flo_rts
  2843.     rts
  2844. flp_sec
  2845.     moveq    #fdd_scty-fdd_ddlk,d7 ; set security level
  2846.     bsr.s    flo_int
  2847.     subq.b    #1,(a0)        ; -1 to 1
  2848.     rts
  2849.  
  2850. flp_start
  2851.     moveq    #fdd_stim-fdd_ddlk,d7 ; set start up time
  2852.     bra.s    flo_dcall
  2853.  
  2854. flp_track
  2855.     moveq    #fdd_ntrk-fdd_ddlk,d7 ; set number of tracks
  2856. flo_dcall
  2857.     bsr.s    flo_int
  2858.     rts
  2859.  
  2860. flo_int
  2861.     move.l    (sp)+,a4     ; remove return address
  2862.     move.w    CA.GTINT,a2    ; get an integer
  2863.     jsr    (a2)
  2864.     bne.s    flo_rts
  2865.     subq.w    #1,d3        ; just one
  2866.     bne    flf_bp
  2867.     bsr    flp_find     ; find the definition block
  2868.     add.w    d7,a0        ; and the item to set
  2869.     move.b    1(a6,a1.l),(a0)    ; and set the byte
  2870.     jmp    (a4)
  2871.  
  2872.     endc
  2873.  
  2874. ; --------------------------------------------------------------
  2875. ; Get a string on the stack V0.2  1985 Tony Tebby QJUMP
  2876. ; Modified to accept numbers and expressions
  2877. ; (C) 1986 David Oliver CST V 4.00
  2878.  
  2879. ut_stos
  2880.     tst.w    2(a6,a3.l)    ; Get name of parameter. If
  2881.                 ; none, it must be exprssn.
  2882.     bmi.s    get_string    ; ... so convert the value
  2883.                 ; to a string.  ** 4.00 **
  2884.     moveq    #$0f,d0        ; extract type of parameter.
  2885.     and.b    1(a6,a3.l),d0
  2886.     subq.b    #1,d0        ; is it a string?
  2887.     bne.s    ut_gtnam     ; ... no, get the name
  2888.                 ; instead
  2889. get_string
  2890.     move.l    a5,-(sp)     ; ... yes, save the top
  2891.                 ; pointer
  2892.     lea    8(a3),a5     ; get just one string
  2893.     move.w    CA.GTSTR,a2
  2894.     jsr    (a2)
  2895.     move.l    (sp)+,a5     ; restore top pointer
  2896.     bne.s    utils_rts
  2897.     moveq    #3,d1        ; get total length of string
  2898.     add.w    0(a6,a1.l),d1
  2899.     bclr    #0,d1
  2900.     add.l    d1,BV_RIP(a6)    ; and reset ri stack pointer
  2901.     bra.s    utils_ok
  2902. ut_gtnam
  2903.     moveq    #ERR.BP,d0    ; assume bad parameter
  2904.     moveq    #0,d1
  2905.     move.w    2(a6,a3.l),d1    ; get the pointer to the
  2906.                 ; real entry
  2907.     bmi.s    utils_rts    ; ... expression is no good
  2908.     lsl.l    #3,d1        ; in multiples of 8 bytes
  2909.     add.l    BV_NTBAS(a6),d1
  2910. ut_ntnam
  2911.     moveq    #0,d6
  2912.     move.w    2(a6,d1.l),d6    ; thus the pointer to the
  2913.                 ; name
  2914.     add.l    BV_NLBAS(a6),d6
  2915.     moveq    #0,d1        ; get the length of the name
  2916.                 ; as a long word
  2917.     move.b    0(a6,d6.l),d1
  2918.     addq.l    #1,d1        ; rounded up
  2919.     bclr    #0,d1
  2920.     move.w    d1,d4        ; and save it
  2921.     addq.l    #2,d1        ; space required is +2 bytes
  2922.     move.w    BV.CHRIX,a2    ; on ri stack
  2923.     jsr    (a2)
  2924.     move.l    BV_RIP(a6),a1
  2925.  
  2926.     add.w    d4,d6        ; move to end of string
  2927.                 ; (ish)
  2928. ut_nam_loop
  2929.     subq.l    #1,a1        ; and copy one byte at a
  2930.                 ; time
  2931.     move.b    0(a6,d6.l),0(a6,a1.l)
  2932.     subq.l    #1,d6
  2933.     dbra    d4,ut_nam_loop    ; including the (byte) name
  2934.                 ; length
  2935.     subq.l    #1,a1        ; put a zero on to make it a
  2936.                 ; word
  2937.     clr.b    0(a6,a1.l)
  2938. utils_ok
  2939.     moveq    #0,d0
  2940. utils_rts
  2941.     rts
  2942. ; --------------------------------------------------------------
  2943. */endfile
  2944.